Software YUV texture support in progress... SDL-1.3
authorSam Lantinga <slouken@libsdl.org>
Sun, 18 Jun 2006 06:35:41 +0000
branchSDL-1.3
changeset 1684c4aa1a2f48f1
parent 1683 396a35389351
child 1685 66267c6a0b12
Software YUV texture support in progress...
include/SDL_pixels.h
src/SDL_compat.c
src/video/SDL_renderer_sw.c
src/video/SDL_video.c
src/video/SDL_yuv_sw.c
src/video/SDL_yuv_sw_c.h
     1.1 --- a/include/SDL_pixels.h	Sat Jun 17 06:45:14 2006 +0000
     1.2 +++ b/include/SDL_pixels.h	Sun Jun 18 06:35:41 2006 +0000
     1.3 @@ -179,11 +179,16 @@
     1.4          SDL_DEFINE_PIXELFORMAT(SDL_PixelType_Packed32, SDL_PackedOrder_ARGB,
     1.5                                 SDL_PackedLayout_2101010, 32, 4),
     1.6  
     1.7 -    SDL_PixelFormat_YV12 = SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2'),
     1.8 -    SDL_PixelFormat_IYUV = SDL_DEFINE_PIXELFOURCC('I', 'Y', 'U', 'V'),
     1.9 -    SDL_PixelFormat_YUY2 = SDL_DEFINE_PIXELFOURCC('Y', 'U', 'Y', '2'),
    1.10 -    SDL_PixelFormat_UYVY = SDL_DEFINE_PIXELFOURCC('U', 'Y', 'V', 'Y'),
    1.11 -    SDL_PixelFormat_YVYU = SDL_DEFINE_PIXELFOURCC('Y', 'V', 'Y', 'U'),
    1.12 +    SDL_PixelFormat_YV12 =      /* Planar mode: Y + V + U  (3 planes) */
    1.13 +        SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2'),
    1.14 +    SDL_PixelFormat_IYUV =      /* Planar mode: Y + U + V  (3 planes) */
    1.15 +        SDL_DEFINE_PIXELFOURCC('I', 'Y', 'U', 'V'),
    1.16 +    SDL_PixelFormat_YUY2 =      /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
    1.17 +        SDL_DEFINE_PIXELFOURCC('Y', 'U', 'Y', '2'),
    1.18 +    SDL_PixelFormat_UYVY =      /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
    1.19 +        SDL_DEFINE_PIXELFOURCC('U', 'Y', 'V', 'Y'),
    1.20 +    SDL_PixelFormat_YVYU =      /* Packed mode: Y0+V0+Y1+U0 (1 plane) */
    1.21 +        SDL_DEFINE_PIXELFOURCC('Y', 'V', 'Y', 'U'),
    1.22  };
    1.23  
    1.24  typedef struct SDL_Color
     2.1 --- a/src/SDL_compat.c	Sat Jun 17 06:45:14 2006 +0000
     2.2 +++ b/src/SDL_compat.c	Sun Jun 18 06:35:41 2006 +0000
     2.3 @@ -1176,121 +1176,159 @@
     2.4          SDL_memset(SDL_cursor->save[0], 0, savelen);
     2.5      }
     2.6  }
     2.7 +#endif
     2.8 +
     2.9 +struct private_yuvhwdata
    2.10 +{
    2.11 +    Uint16 pitches[3];
    2.12 +    Uint8 *planes[3];
    2.13 +
    2.14 +    SDL_TextureID textureID;
    2.15 +};
    2.16  
    2.17  SDL_Overlay *
    2.18  SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display)
    2.19  {
    2.20 -    SDL_VideoDevice *_this = SDL_GetVideoDevice();
    2.21 -    SDL_Window *window;
    2.22 -    const char *yuv_hwaccel;
    2.23      SDL_Overlay *overlay;
    2.24 +    Uint32 texture_format;
    2.25  
    2.26 -    window = SDL_GetWindowFromSurface(display);
    2.27 -    if (window && (window->flags & SDL_WINDOW_OPENGL)) {
    2.28 +    if ((display->flags & SDL_OPENGL) == SDL_OPENGL) {
    2.29          SDL_SetError("YUV overlays are not supported in OpenGL mode");
    2.30          return NULL;
    2.31      }
    2.32  
    2.33 -    /* Display directly on video surface, if possible */
    2.34 -    if (SDL_getenv("SDL_VIDEO_YUV_DIRECT")) {
    2.35 -        if (window &&
    2.36 -            ((window->surface->format->BytesPerPixel == 2) ||
    2.37 -             (window->surface->format->BytesPerPixel == 4))) {
    2.38 -            display = window->surface;
    2.39 -        }
    2.40 +    if (display != SDL_PublicSurface) {
    2.41 +        SDL_SetError("YUV display is only supported on the screen surface");
    2.42 +        return NULL;
    2.43      }
    2.44 -    overlay = NULL;
    2.45 -    yuv_hwaccel = SDL_getenv("SDL_VIDEO_YUV_HWACCEL");
    2.46 -    if (((display->flags & SDL_SCREEN_SURFACE) && _this->CreateYUVOverlay) &&
    2.47 -        (!yuv_hwaccel || (SDL_atoi(yuv_hwaccel) > 0))) {
    2.48 -        overlay = _this->CreateYUVOverlay(_this, w, h, format, display);
    2.49 +
    2.50 +    switch (format) {
    2.51 +    case SDL_YV12_OVERLAY:
    2.52 +        texture_format = SDL_PixelFormat_YV12;
    2.53 +        break;
    2.54 +    case SDL_IYUV_OVERLAY:
    2.55 +        texture_format = SDL_PixelFormat_IYUV;
    2.56 +        break;
    2.57 +    case SDL_YUY2_OVERLAY:
    2.58 +        texture_format = SDL_PixelFormat_YUY2;
    2.59 +        break;
    2.60 +    case SDL_UYVY_OVERLAY:
    2.61 +        texture_format = SDL_PixelFormat_UYVY;
    2.62 +        break;
    2.63 +    case SDL_YVYU_OVERLAY:
    2.64 +        texture_format = SDL_PixelFormat_YVYU;
    2.65 +        break;
    2.66 +    default:
    2.67 +        SDL_SetError("Unknown YUV format");
    2.68 +        return NULL;
    2.69      }
    2.70 -    /* If hardware YUV overlay failed ... */
    2.71 -    if (overlay == NULL) {
    2.72 -        overlay = SDL_CreateYUV_SW(_this, w, h, format, display);
    2.73 +
    2.74 +    overlay = (SDL_Overlay *) SDL_malloc(sizeof(*overlay));
    2.75 +    if (!overlay) {
    2.76 +        SDL_OutOfMemory();
    2.77 +        return NULL;
    2.78      }
    2.79 +    SDL_zerop(overlay);
    2.80 +
    2.81 +    overlay->hwdata =
    2.82 +        (struct private_yuvhwdata *) SDL_malloc(sizeof(*overlay->hwdata));
    2.83 +    if (!overlay->hwdata) {
    2.84 +        SDL_free(overlay);
    2.85 +        SDL_OutOfMemory();
    2.86 +        return NULL;
    2.87 +    }
    2.88 +
    2.89 +    overlay->format = format;
    2.90 +    overlay->w = w;
    2.91 +    overlay->h = h;
    2.92 +    if (format == SDL_YV12_OVERLAY || format == SDL_IYUV_OVERLAY) {
    2.93 +        overlay->planes = 3;
    2.94 +    } else {
    2.95 +        overlay->planes = 1;
    2.96 +    }
    2.97 +    overlay->pitches = overlay->hwdata->pitches;
    2.98 +    overlay->pixels = overlay->hwdata->planes;
    2.99 +
   2.100 +    switch (format) {
   2.101 +    case SDL_YV12_OVERLAY:
   2.102 +    case SDL_IYUV_OVERLAY:
   2.103 +        overlay->pitches[0] = overlay->w;
   2.104 +        overlay->pitches[1] = overlay->w / 2;
   2.105 +        overlay->pitches[2] = overlay->w / 2;
   2.106 +        break;
   2.107 +    case SDL_YUY2_OVERLAY:
   2.108 +    case SDL_UYVY_OVERLAY:
   2.109 +    case SDL_YVYU_OVERLAY:
   2.110 +        overlay->pitches[0] = overlay->h * 2;
   2.111 +        break;
   2.112 +    }
   2.113 +
   2.114 +    overlay->hwdata->textureID =
   2.115 +        SDL_CreateTexture(texture_format, SDL_TextureAccess_Local, w, h);
   2.116 +    if (!overlay->hwdata->textureID) {
   2.117 +        SDL_FreeYUVOverlay(overlay);
   2.118 +        return NULL;
   2.119 +    }
   2.120 +
   2.121      return overlay;
   2.122  }
   2.123  
   2.124  int
   2.125  SDL_LockYUVOverlay(SDL_Overlay * overlay)
   2.126  {
   2.127 -    SDL_VideoDevice *_this = SDL_GetVideoDevice();
   2.128 -    return overlay->hwfuncs->Lock(_this, overlay);
   2.129 +    void *pixels;
   2.130 +    int pitch;
   2.131 +    if (SDL_LockTexture(overlay->hwdata->textureID, NULL, 1, &pixels, &pitch)
   2.132 +        < 0) {
   2.133 +        return -1;
   2.134 +    }
   2.135 +    switch (overlay->format) {
   2.136 +    case SDL_YV12_OVERLAY:
   2.137 +    case SDL_IYUV_OVERLAY:
   2.138 +        overlay->pixels[0] = (Uint8 *) pixels;
   2.139 +        overlay->pixels[1] =
   2.140 +            overlay->pixels[0] + overlay->pitches[0] * overlay->h;
   2.141 +        overlay->pixels[2] =
   2.142 +            overlay->pixels[1] + overlay->pitches[1] * overlay->h;
   2.143 +        break;
   2.144 +    case SDL_YUY2_OVERLAY:
   2.145 +    case SDL_UYVY_OVERLAY:
   2.146 +    case SDL_YVYU_OVERLAY:
   2.147 +        overlay->pixels[0] = (Uint8 *) pixels;
   2.148 +        break;
   2.149 +    }
   2.150 +    return 0;
   2.151  }
   2.152  
   2.153  void
   2.154  SDL_UnlockYUVOverlay(SDL_Overlay * overlay)
   2.155  {
   2.156 -    SDL_VideoDevice *_this = SDL_GetVideoDevice();
   2.157 -    overlay->hwfuncs->Unlock(_this, overlay);
   2.158 +    SDL_UnlockTexture(overlay->hwdata->textureID);
   2.159  }
   2.160  
   2.161  int
   2.162  SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect)
   2.163  {
   2.164 -    SDL_VideoDevice *_this = SDL_GetVideoDevice();
   2.165 -    SDL_Rect src, dst;
   2.166 -    int srcx, srcy, srcw, srch;
   2.167 -    int dstx, dsty, dstw, dsth;
   2.168 -
   2.169 -    /* Clip the rectangle to the screen area */
   2.170 -    srcx = 0;
   2.171 -    srcy = 0;
   2.172 -    srcw = overlay->w;
   2.173 -    srch = overlay->h;
   2.174 -    dstx = dstrect->x;
   2.175 -    dsty = dstrect->y;
   2.176 -    dstw = dstrect->w;
   2.177 -    dsth = dstrect->h;
   2.178 -    if (dstx < 0) {
   2.179 -        srcw += (dstx * overlay->w) / dstrect->w;
   2.180 -        dstw += dstx;
   2.181 -        srcx -= (dstx * overlay->w) / dstrect->w;
   2.182 -        dstx = 0;
   2.183 +    if (SDL_RenderCopy(overlay->hwdata->textureID, NULL, dstrect,
   2.184 +                       SDL_TextureBlendMode_None,
   2.185 +                       SDL_TextureScaleMode_Fast) < 0) {
   2.186 +        return -1;
   2.187      }
   2.188 -    if ((dstx + dstw) > SDL_VideoSurface->w) {
   2.189 -        int extra = (dstx + dstw - SDL_VideoSurface->w);
   2.190 -        srcw -= (extra * overlay->w) / dstrect->w;
   2.191 -        dstw -= extra;
   2.192 -    }
   2.193 -    if (dsty < 0) {
   2.194 -        srch += (dsty * overlay->h) / dstrect->h;
   2.195 -        dsth += dsty;
   2.196 -        srcy -= (dsty * overlay->h) / dstrect->h;
   2.197 -        dsty = 0;
   2.198 -    }
   2.199 -    if ((dsty + dsth) > SDL_VideoSurface->h) {
   2.200 -        int extra = (dsty + dsth - SDL_VideoSurface->h);
   2.201 -        srch -= (extra * overlay->h) / dstrect->h;
   2.202 -        dsth -= extra;
   2.203 -    }
   2.204 -    if (srcw <= 0 || srch <= 0 || srch <= 0 || dsth <= 0) {
   2.205 -        return 0;
   2.206 -    }
   2.207 -    /* Ugh, I can't wait for SDL_Rect to be int values */
   2.208 -    src.x = srcx;
   2.209 -    src.y = srcy;
   2.210 -    src.w = srcw;
   2.211 -    src.h = srch;
   2.212 -    dst.x = dstx;
   2.213 -    dst.y = dsty;
   2.214 -    dst.w = dstw;
   2.215 -    dst.h = dsth;
   2.216 -    return overlay->hwfuncs->Display(_this, overlay, &src, &dst);
   2.217 +    SDL_RenderPresent();
   2.218  }
   2.219  
   2.220  void
   2.221  SDL_FreeYUVOverlay(SDL_Overlay * overlay)
   2.222  {
   2.223 -    SDL_VideoDevice *_this = SDL_GetVideoDevice();
   2.224      if (overlay) {
   2.225 -        if (overlay->hwfuncs) {
   2.226 -            overlay->hwfuncs->FreeHW(_this, overlay);
   2.227 +        if (overlay->hwdata) {
   2.228 +            if (overlay->hwdata->textureID) {
   2.229 +                SDL_DestroyTexture(overlay->hwdata->textureID);
   2.230 +            }
   2.231 +            SDL_free(overlay->hwdata);
   2.232          }
   2.233          SDL_free(overlay);
   2.234      }
   2.235  }
   2.236 -#endif
   2.237  
   2.238  /* vi: set ts=4 sw=4 expandtab: */
     3.1 --- a/src/video/SDL_renderer_sw.c	Sat Jun 17 06:45:14 2006 +0000
     3.2 +++ b/src/video/SDL_renderer_sw.c	Sun Jun 18 06:35:41 2006 +0000
     3.3 @@ -23,6 +23,7 @@
     3.4  
     3.5  #include "SDL_video.h"
     3.6  #include "SDL_sysvideo.h"
     3.7 +#include "SDL_yuv_sw_c.h"
     3.8  
     3.9  
    3.10  /* SDL surface based renderer implementation */
    3.11 @@ -205,29 +206,30 @@
    3.12  static int
    3.13  SDL_SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
    3.14  {
    3.15 -    SDL_Surface *surface;
    3.16 -    int bpp;
    3.17 -    Uint32 Rmask, Gmask, Bmask, Amask;
    3.18 +    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
    3.19 +        if (texture->access == SDL_TextureAccess_Render) {
    3.20 +            SDL_SetError("Rendering to YUV format textures is not supported");
    3.21 +            return -1;
    3.22 +        }
    3.23 +        texture->driverdata = SDL_SW_CreateYUVTexture(texture);
    3.24 +    } else {
    3.25 +        int bpp;
    3.26 +        Uint32 Rmask, Gmask, Bmask, Amask;
    3.27  
    3.28 -    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
    3.29 -        /* FIXME: implement this */
    3.30 +        if (!SDL_PixelFormatEnumToMasks
    3.31 +            (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
    3.32 +            SDL_SetError("Unknown texture format");
    3.33 +            return -1;
    3.34 +        }
    3.35 +
    3.36 +        texture->driverdata =
    3.37 +            SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask,
    3.38 +                                 Bmask, Amask);
    3.39 +    }
    3.40 +
    3.41 +    if (!texture->driverdata) {
    3.42          return -1;
    3.43      }
    3.44 -
    3.45 -    if (!SDL_PixelFormatEnumToMasks
    3.46 -        (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
    3.47 -        SDL_SetError("Unknown texture format");
    3.48 -        return -1;
    3.49 -    }
    3.50 -
    3.51 -    surface =
    3.52 -        SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask,
    3.53 -                             Bmask, Amask);
    3.54 -    if (!surface) {
    3.55 -        return -1;
    3.56 -    }
    3.57 -
    3.58 -    texture->driverdata = surface;
    3.59      return 0;
    3.60  }
    3.61  
    3.62 @@ -235,11 +237,16 @@
    3.63  SDL_SW_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
    3.64                            void **pixels, int *pitch)
    3.65  {
    3.66 -    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
    3.67 +    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
    3.68 +        return SDL_SW_QueryYUVTexturePixels((SDL_SW_YUVTexture *) texture->
    3.69 +                                            driverdata, pixels, pitch);
    3.70 +    } else {
    3.71 +        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
    3.72  
    3.73 -    *pixels = surface->pixels;
    3.74 -    *pitch = surface->pitch;
    3.75 -    return 0;
    3.76 +        *pixels = surface->pixels;
    3.77 +        *pitch = surface->pitch;
    3.78 +        return 0;
    3.79 +    }
    3.80  }
    3.81  
    3.82  static int
    3.83 @@ -247,43 +254,58 @@
    3.84                           const SDL_Color * colors, int firstcolor,
    3.85                           int ncolors)
    3.86  {
    3.87 -    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
    3.88 +    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
    3.89 +        SDL_SetError("YUV textures don't have a palette");
    3.90 +        return -1;
    3.91 +    } else {
    3.92 +        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
    3.93  
    3.94 -    return SDL_SetPaletteColors(surface->format->palette, colors, firstcolor,
    3.95 -                                ncolors);
    3.96 +        return SDL_SetPaletteColors(surface->format->palette, colors,
    3.97 +                                    firstcolor, ncolors);
    3.98 +    }
    3.99  }
   3.100  
   3.101  static int
   3.102  SDL_SW_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
   3.103                           SDL_Color * colors, int firstcolor, int ncolors)
   3.104  {
   3.105 -    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   3.106 +    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
   3.107 +        SDL_SetError("YUV textures don't have a palette");
   3.108 +        return -1;
   3.109 +    } else {
   3.110 +        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   3.111  
   3.112 -    SDL_memcpy(colors, &surface->format->palette->colors[firstcolor],
   3.113 -               ncolors * sizeof(*colors));
   3.114 -    return 0;
   3.115 +        SDL_memcpy(colors, &surface->format->palette->colors[firstcolor],
   3.116 +                   ncolors * sizeof(*colors));
   3.117 +        return 0;
   3.118 +    }
   3.119  }
   3.120  
   3.121  static int
   3.122  SDL_SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   3.123                       const SDL_Rect * rect, const void *pixels, int pitch)
   3.124  {
   3.125 -    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   3.126 -    Uint8 *src, *dst;
   3.127 -    int row;
   3.128 -    size_t length;
   3.129 +    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
   3.130 +        return SDL_SW_UpdateYUVTexture((SDL_SW_YUVTexture *) texture->
   3.131 +                                       driverdata, rect, pixels, pitch);
   3.132 +    } else {
   3.133 +        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   3.134 +        Uint8 *src, *dst;
   3.135 +        int row;
   3.136 +        size_t length;
   3.137  
   3.138 -    src = (Uint8 *) pixels;
   3.139 -    dst =
   3.140 -        (Uint8 *) surface->pixels + rect->y * surface->pitch +
   3.141 -        rect->x * surface->format->BytesPerPixel;
   3.142 -    length = rect->w * surface->format->BytesPerPixel;
   3.143 -    for (row = 0; row < rect->h; ++row) {
   3.144 -        SDL_memcpy(dst, src, length);
   3.145 -        src += pitch;
   3.146 -        dst += surface->pitch;
   3.147 +        src = (Uint8 *) pixels;
   3.148 +        dst =
   3.149 +            (Uint8 *) surface->pixels + rect->y * surface->pitch +
   3.150 +            rect->x * surface->format->BytesPerPixel;
   3.151 +        length = rect->w * surface->format->BytesPerPixel;
   3.152 +        for (row = 0; row < rect->h; ++row) {
   3.153 +            SDL_memcpy(dst, src, length);
   3.154 +            src += pitch;
   3.155 +            dst += surface->pitch;
   3.156 +        }
   3.157 +        return 0;
   3.158      }
   3.159 -    return 0;
   3.160  }
   3.161  
   3.162  static int
   3.163 @@ -291,18 +313,27 @@
   3.164                     const SDL_Rect * rect, int markDirty, void **pixels,
   3.165                     int *pitch)
   3.166  {
   3.167 -    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   3.168 +    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
   3.169 +        return SDL_SW_LockYUVTexture((SDL_SW_YUVTexture *) texture->
   3.170 +                                     driverdata, rect, markDirty, pixels,
   3.171 +                                     pitch);
   3.172 +    } else {
   3.173 +        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   3.174  
   3.175 -    *pixels =
   3.176 -        (void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch +
   3.177 -                  rect->x * surface->format->BytesPerPixel);
   3.178 -    *pitch = surface->pitch;
   3.179 -    return 0;
   3.180 +        *pixels =
   3.181 +            (void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch +
   3.182 +                      rect->x * surface->format->BytesPerPixel);
   3.183 +        *pitch = surface->pitch;
   3.184 +        return 0;
   3.185 +    }
   3.186  }
   3.187  
   3.188  static void
   3.189  SDL_SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   3.190  {
   3.191 +    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
   3.192 +        SDL_SW_UnlockYUVTexture((SDL_SW_YUVTexture *) texture->driverdata);
   3.193 +    }
   3.194  }
   3.195  
   3.196  static void
   3.197 @@ -346,22 +377,36 @@
   3.198                    int blendMode, int scaleMode)
   3.199  {
   3.200      SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata;
   3.201 -    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   3.202 -    SDL_Rect real_srcrect = *srcrect;
   3.203 -    SDL_Rect real_dstrect = *dstrect;
   3.204  
   3.205 -    if (blendMode & (SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend)) {
   3.206 -        SDL_SetAlpha(surface, SDL_SRCALPHA, 0);
   3.207 +    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
   3.208 +        SDL_Surface *target = data->target;
   3.209 +        void *pixels =
   3.210 +            (Uint8 *) target->pixels + dstrect->y * target->pitch +
   3.211 +            dstrect->x * target->format->BytesPerPixel;
   3.212 +        return SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata,
   3.213 +                                   srcrect,
   3.214 +                                   renderer->window->display->current_mode.
   3.215 +                                   format, dstrect->w, dstrect->h, pixels,
   3.216 +                                   target->pitch);
   3.217      } else {
   3.218 -        SDL_SetAlpha(surface, 0, 0);
   3.219 -    }
   3.220 -    if (scaleMode != SDL_TextureScaleMode_None &&
   3.221 -        (srcrect->w != dstrect->w || srcrect->h != dstrect->h)) {
   3.222 -        return SDL_SoftStretch(surface, &real_srcrect, data->target,
   3.223 -                               &real_dstrect);
   3.224 -    } else {
   3.225 -        return SDL_LowerBlit(surface, &real_srcrect, data->target,
   3.226 -                             &real_dstrect);
   3.227 +        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   3.228 +        SDL_Rect real_srcrect = *srcrect;
   3.229 +        SDL_Rect real_dstrect = *dstrect;
   3.230 +
   3.231 +        if (blendMode &
   3.232 +            (SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend)) {
   3.233 +            SDL_SetAlpha(surface, SDL_SRCALPHA, 0);
   3.234 +        } else {
   3.235 +            SDL_SetAlpha(surface, 0, 0);
   3.236 +        }
   3.237 +        if (scaleMode != SDL_TextureScaleMode_None &&
   3.238 +            (srcrect->w != dstrect->w || srcrect->h != dstrect->h)) {
   3.239 +            return SDL_SoftStretch(surface, &real_srcrect, data->target,
   3.240 +                                   &real_dstrect);
   3.241 +        } else {
   3.242 +            return SDL_LowerBlit(surface, &real_srcrect, data->target,
   3.243 +                                 &real_dstrect);
   3.244 +        }
   3.245      }
   3.246  }
   3.247  
   3.248 @@ -446,9 +491,13 @@
   3.249  static void
   3.250  SDL_SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   3.251  {
   3.252 -    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   3.253 +    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
   3.254 +        SDL_SW_DestroyYUVTexture((SDL_SW_YUVTexture *) texture->driverdata);
   3.255 +    } else {
   3.256 +        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   3.257  
   3.258 -    SDL_FreeSurface(surface);
   3.259 +        SDL_FreeSurface(surface);
   3.260 +    }
   3.261  }
   3.262  
   3.263  static void
     4.1 --- a/src/video/SDL_video.c	Sat Jun 17 06:45:14 2006 +0000
     4.2 +++ b/src/video/SDL_video.c	Sun Jun 18 06:35:41 2006 +0000
     4.3 @@ -567,7 +567,7 @@
     4.4          ncolors = 0;
     4.5      }
     4.6      if ((!ncolors && display->palette) || (ncolors && !display->palette)
     4.7 -        || (ncolors != display->palette->ncolors)) {
     4.8 +        || (ncolors && ncolors != display->palette->ncolors)) {
     4.9          if (display->palette) {
    4.10              SDL_FreePalette(display->palette);
    4.11              display->palette = NULL;
    4.12 @@ -1434,6 +1434,7 @@
    4.13  {
    4.14      SDL_Texture *texture = SDL_GetTextureFromID(textureID);
    4.15      SDL_Renderer *renderer;
    4.16 +    SDL_Rect full_rect;
    4.17  
    4.18      if (!texture) {
    4.19          return -1;
    4.20 @@ -1443,6 +1444,15 @@
    4.21      if (!renderer->UpdateTexture) {
    4.22          return -1;
    4.23      }
    4.24 +
    4.25 +    if (!rect) {
    4.26 +        full_rect.x = 0;
    4.27 +        full_rect.y = 0;
    4.28 +        full_rect.w = texture->w;
    4.29 +        full_rect.h = texture->h;
    4.30 +        rect = &full_rect;
    4.31 +    }
    4.32 +
    4.33      return renderer->UpdateTexture(renderer, texture, rect, pixels, pitch);
    4.34  }
    4.35  
    4.36 @@ -1452,6 +1462,7 @@
    4.37  {
    4.38      SDL_Texture *texture = SDL_GetTextureFromID(textureID);
    4.39      SDL_Renderer *renderer;
    4.40 +    SDL_Rect full_rect;
    4.41  
    4.42      if (!texture) {
    4.43          return -1;
    4.44 @@ -1461,6 +1472,15 @@
    4.45      if (!renderer->LockTexture) {
    4.46          return -1;
    4.47      }
    4.48 +
    4.49 +    if (!rect) {
    4.50 +        full_rect.x = 0;
    4.51 +        full_rect.y = 0;
    4.52 +        full_rect.w = texture->w;
    4.53 +        full_rect.h = texture->h;
    4.54 +        rect = &full_rect;
    4.55 +    }
    4.56 +
    4.57      return renderer->LockTexture(renderer, texture, rect, markDirty, pixels,
    4.58                                   pitch);
    4.59  }
    4.60 @@ -1520,6 +1540,7 @@
    4.61  SDL_RenderFill(const SDL_Rect * rect, Uint32 color)
    4.62  {
    4.63      SDL_Renderer *renderer;
    4.64 +    SDL_Rect full_rect;
    4.65  
    4.66      if (!_this) {
    4.67          return -1;
    4.68 @@ -1530,6 +1551,14 @@
    4.69          return -1;
    4.70      }
    4.71  
    4.72 +    if (!rect) {
    4.73 +        full_rect.x = 0;
    4.74 +        full_rect.y = 0;
    4.75 +        full_rect.w = renderer->window->w;
    4.76 +        full_rect.h = renderer->window->h;
    4.77 +        rect = &full_rect;
    4.78 +    }
    4.79 +
    4.80      renderer->RenderFill(renderer, rect, color);
    4.81  }
    4.82  
    4.83 @@ -1539,6 +1568,8 @@
    4.84  {
    4.85      SDL_Texture *texture = SDL_GetTextureFromID(textureID);
    4.86      SDL_Renderer *renderer;
    4.87 +    SDL_Rect full_srcrect;
    4.88 +    SDL_Rect full_dstrect;
    4.89  
    4.90      if (!texture || texture->renderer != SDL_CurrentDisplay.current_renderer) {
    4.91          return;
    4.92 @@ -1549,6 +1580,21 @@
    4.93          return -1;
    4.94      }
    4.95  
    4.96 +    if (!srcrect) {
    4.97 +        full_srcrect.x = 0;
    4.98 +        full_srcrect.y = 0;
    4.99 +        full_srcrect.w = texture->w;
   4.100 +        full_srcrect.h = texture->h;
   4.101 +        srcrect = &full_srcrect;
   4.102 +    }
   4.103 +    if (!dstrect) {
   4.104 +        full_dstrect.x = 0;
   4.105 +        full_dstrect.y = 0;
   4.106 +        full_dstrect.w = renderer->window->w;
   4.107 +        full_dstrect.h = renderer->window->h;
   4.108 +        dstrect = &full_dstrect;
   4.109 +    }
   4.110 +
   4.111      return renderer->RenderCopy(renderer, texture, srcrect, dstrect,
   4.112                                  blendMode, scaleMode);
   4.113  }
   4.114 @@ -1557,6 +1603,7 @@
   4.115  SDL_RenderReadPixels(const SDL_Rect * rect, void *pixels, int pitch)
   4.116  {
   4.117      SDL_Renderer *renderer;
   4.118 +    SDL_Rect full_rect;
   4.119  
   4.120      if (!_this) {
   4.121          return -1;
   4.122 @@ -1567,6 +1614,14 @@
   4.123          return -1;
   4.124      }
   4.125  
   4.126 +    if (!rect) {
   4.127 +        full_rect.x = 0;
   4.128 +        full_rect.y = 0;
   4.129 +        full_rect.w = renderer->window->w;
   4.130 +        full_rect.h = renderer->window->h;
   4.131 +        rect = &full_rect;
   4.132 +    }
   4.133 +
   4.134      return renderer->RenderReadPixels(renderer, rect, pixels, pitch);
   4.135  }
   4.136  
   4.137 @@ -1574,6 +1629,7 @@
   4.138  SDL_RenderWritePixels(const SDL_Rect * rect, const void *pixels, int pitch)
   4.139  {
   4.140      SDL_Renderer *renderer;
   4.141 +    SDL_Rect full_rect;
   4.142  
   4.143      if (!_this) {
   4.144          return -1;
   4.145 @@ -1584,6 +1640,14 @@
   4.146          return -1;
   4.147      }
   4.148  
   4.149 +    if (!rect) {
   4.150 +        full_rect.x = 0;
   4.151 +        full_rect.y = 0;
   4.152 +        full_rect.w = renderer->window->w;
   4.153 +        full_rect.h = renderer->window->h;
   4.154 +        rect = &full_rect;
   4.155 +    }
   4.156 +
   4.157      return renderer->RenderWritePixels(renderer, rect, pixels, pitch);
   4.158  }
   4.159  
     5.1 --- a/src/video/SDL_yuv_sw.c	Sat Jun 17 06:45:14 2006 +0000
     5.2 +++ b/src/video/SDL_yuv_sw.c	Sun Jun 18 06:35:41 2006 +0000
     5.3 @@ -21,8 +21,7 @@
     5.4  */
     5.5  #include "SDL_config.h"
     5.6  
     5.7 -#if 0                           /* TODO */
     5.8 -/* This is the software implementation of the YUV video overlay support */
     5.9 +/* This is the software implementation of the YUV texture support */
    5.10  
    5.11  /* This code was derived from code carrying the following copyright notices:
    5.12  
    5.13 @@ -87,22 +86,14 @@
    5.14  #include "SDL_video.h"
    5.15  #include "SDL_cpuinfo.h"
    5.16  #include "SDL_stretch_c.h"
    5.17 -#include "SDL_yuvfuncs.h"
    5.18  #include "SDL_yuv_sw_c.h"
    5.19  
    5.20 -/* The functions used to manipulate software video overlays */
    5.21 -static struct private_yuvhwfuncs sw_yuvfuncs = {
    5.22 -    SDL_LockYUV_SW,
    5.23 -    SDL_UnlockYUV_SW,
    5.24 -    SDL_DisplayYUV_SW,
    5.25 -    SDL_FreeYUV_SW
    5.26 -};
    5.27  
    5.28 -/* RGB conversion lookup tables */
    5.29 -struct private_yuvhwdata
    5.30 +struct SDL_SW_YUVTexture
    5.31  {
    5.32 -    SDL_Surface *stretch;
    5.33 -    SDL_Surface *display;
    5.34 +    SDL_Texture *texture;
    5.35 +
    5.36 +    Uint32 target_format;
    5.37      Uint8 *pixels;
    5.38      int *colortab;
    5.39      Uint32 *rgb_2_pix;
    5.40 @@ -118,9 +109,12 @@
    5.41      /* These are just so we don't have to allocate them separately */
    5.42      Uint16 pitches[3];
    5.43      Uint8 *planes[3];
    5.44 +
    5.45 +    /* This is a temporary surface in case we have to stretch copy */
    5.46 +    SDL_Surface *stretch;
    5.47 +    SDL_Surface *display;
    5.48  };
    5.49  
    5.50 -
    5.51  /* The colorspace conversion functions */
    5.52  
    5.53  #if 0                           /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES */
    5.54 @@ -918,105 +912,30 @@
    5.55      return 1 + free_bits_at_bottom(a >> 1);
    5.56  }
    5.57  
    5.58 -
    5.59 -SDL_Overlay *
    5.60 -SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format,
    5.61 -                 SDL_Surface * display)
    5.62 +static int
    5.63 +SDL_SW_SetupYUVDisplay(SDL_SW_YUVTexture * swdata, Uint32 target_format)
    5.64  {
    5.65 -    SDL_Overlay *overlay;
    5.66 -    struct private_yuvhwdata *swdata;
    5.67 -    int *Cr_r_tab;
    5.68 -    int *Cr_g_tab;
    5.69 -    int *Cb_g_tab;
    5.70 -    int *Cb_b_tab;
    5.71      Uint32 *r_2_pix_alloc;
    5.72      Uint32 *g_2_pix_alloc;
    5.73      Uint32 *b_2_pix_alloc;
    5.74      int i;
    5.75 -    int CR, CB;
    5.76 -    Uint32 Rmask, Gmask, Bmask;
    5.77 +    int bpp;
    5.78 +    Uint32 Rmask, Gmask, Bmask, Amask;
    5.79  
    5.80 -    /* Only RGB packed pixel conversion supported */
    5.81 -    if ((display->format->BytesPerPixel != 2) &&
    5.82 -        (display->format->BytesPerPixel != 3) &&
    5.83 -        (display->format->BytesPerPixel != 4)) {
    5.84 -        SDL_SetError("Can't use YUV data on non 16/24/32 bit surfaces");
    5.85 -        return (NULL);
    5.86 +    if (!SDL_PixelFormatEnumToMasks
    5.87 +        (target_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask) || bpp < 15) {
    5.88 +        SDL_SetError("Unsupported YUV destination format");
    5.89 +        return -1;
    5.90      }
    5.91  
    5.92 -    /* Verify that we support the format */
    5.93 -    switch (format) {
    5.94 -    case SDL_YV12_OVERLAY:
    5.95 -    case SDL_IYUV_OVERLAY:
    5.96 -    case SDL_YUY2_OVERLAY:
    5.97 -    case SDL_UYVY_OVERLAY:
    5.98 -    case SDL_YVYU_OVERLAY:
    5.99 -        break;
   5.100 -    default:
   5.101 -        SDL_SetError("Unsupported YUV format");
   5.102 -        return (NULL);
   5.103 -    }
   5.104 -
   5.105 -    /* Create the overlay structure */
   5.106 -    overlay = (SDL_Overlay *) SDL_malloc(sizeof *overlay);
   5.107 -    if (overlay == NULL) {
   5.108 -        SDL_OutOfMemory();
   5.109 -        return (NULL);
   5.110 -    }
   5.111 -    SDL_memset(overlay, 0, (sizeof *overlay));
   5.112 -
   5.113 -    /* Fill in the basic members */
   5.114 -    overlay->format = format;
   5.115 -    overlay->w = width;
   5.116 -    overlay->h = height;
   5.117 -
   5.118 -    /* Set up the YUV surface function structure */
   5.119 -    overlay->hwfuncs = &sw_yuvfuncs;
   5.120 -
   5.121 -    /* Create the pixel data and lookup tables */
   5.122 -    swdata = (struct private_yuvhwdata *) SDL_malloc(sizeof *swdata);
   5.123 -    overlay->hwdata = swdata;
   5.124 -    if (swdata == NULL) {
   5.125 -        SDL_OutOfMemory();
   5.126 -        SDL_FreeYUVOverlay(overlay);
   5.127 -        return (NULL);
   5.128 -    }
   5.129 -    swdata->stretch = NULL;
   5.130 -    swdata->display = display;
   5.131 -    swdata->pixels = (Uint8 *) SDL_malloc(width * height * 2);
   5.132 -    swdata->colortab = (int *) SDL_malloc(4 * 256 * sizeof(int));
   5.133 -    Cr_r_tab = &swdata->colortab[0 * 256];
   5.134 -    Cr_g_tab = &swdata->colortab[1 * 256];
   5.135 -    Cb_g_tab = &swdata->colortab[2 * 256];
   5.136 -    Cb_b_tab = &swdata->colortab[3 * 256];
   5.137 -    swdata->rgb_2_pix = (Uint32 *) SDL_malloc(3 * 768 * sizeof(Uint32));
   5.138 +    swdata->target_format = target_format;
   5.139      r_2_pix_alloc = &swdata->rgb_2_pix[0 * 768];
   5.140      g_2_pix_alloc = &swdata->rgb_2_pix[1 * 768];
   5.141      b_2_pix_alloc = &swdata->rgb_2_pix[2 * 768];
   5.142 -    if (!swdata->pixels || !swdata->colortab || !swdata->rgb_2_pix) {
   5.143 -        SDL_OutOfMemory();
   5.144 -        SDL_FreeYUVOverlay(overlay);
   5.145 -        return (NULL);
   5.146 -    }
   5.147 -
   5.148 -    /* Generate the tables for the display surface */
   5.149 -    for (i = 0; i < 256; i++) {
   5.150 -        /* Gamma correction (luminescence table) and chroma correction
   5.151 -           would be done here.  See the Berkeley mpeg_play sources.
   5.152 -         */
   5.153 -        CB = CR = (i - 128);
   5.154 -        Cr_r_tab[i] = (int) ((0.419 / 0.299) * CR);
   5.155 -        Cr_g_tab[i] = (int) (-(0.299 / 0.419) * CR);
   5.156 -        Cb_g_tab[i] = (int) (-(0.114 / 0.331) * CB);
   5.157 -        Cb_b_tab[i] = (int) ((0.587 / 0.331) * CB);
   5.158 -    }
   5.159  
   5.160      /* 
   5.161       * Set up entries 0-255 in rgb-to-pixel value tables.
   5.162       */
   5.163 -    Rmask = display->format->Rmask;
   5.164 -    Gmask = display->format->Gmask;
   5.165 -    Bmask = display->format->Bmask;
   5.166      for (i = 0; i < 256; ++i) {
   5.167          r_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(Rmask));
   5.168          r_2_pix_alloc[i + 256] <<= free_bits_at_bottom(Rmask);
   5.169 @@ -1033,7 +952,7 @@
   5.170       * harmless in the normal case as storing a 32-bit value
   5.171       * through a short pointer will lose the top bits anyway.
   5.172       */
   5.173 -    if (display->format->BytesPerPixel == 2) {
   5.174 +    if (SDL_BYTESPERPIXEL(target_format) == 2) {
   5.175          for (i = 0; i < 256; ++i) {
   5.176              r_2_pix_alloc[i + 256] |= (r_2_pix_alloc[i + 256]) << 16;
   5.177              g_2_pix_alloc[i + 256] |= (g_2_pix_alloc[i + 256]) << 16;
   5.178 @@ -1055,10 +974,10 @@
   5.179      }
   5.180  
   5.181      /* You have chosen wisely... */
   5.182 -    switch (format) {
   5.183 -    case SDL_YV12_OVERLAY:
   5.184 -    case SDL_IYUV_OVERLAY:
   5.185 -        if (display->format->BytesPerPixel == 2) {
   5.186 +    switch (swdata->texture->format) {
   5.187 +    case SDL_PixelFormat_YV12:
   5.188 +    case SDL_PixelFormat_IYUV:
   5.189 +        if (SDL_BYTESPERPIXEL(target_format) == 2) {
   5.190  #if 0                           /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES */
   5.191              /* inline assembly functions */
   5.192              if (SDL_HasMMX() && (Rmask == 0xF800) &&
   5.193 @@ -1074,11 +993,11 @@
   5.194  #endif
   5.195              swdata->Display2X = Color16DitherYV12Mod2X;
   5.196          }
   5.197 -        if (display->format->BytesPerPixel == 3) {
   5.198 +        if (SDL_BYTESPERPIXEL(target_format) == 3) {
   5.199              swdata->Display1X = Color24DitherYV12Mod1X;
   5.200              swdata->Display2X = Color24DitherYV12Mod2X;
   5.201          }
   5.202 -        if (display->format->BytesPerPixel == 4) {
   5.203 +        if (SDL_BYTESPERPIXEL(target_format) == 4) {
   5.204  #if 0                           /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES */
   5.205              /* inline assembly functions */
   5.206              if (SDL_HasMMX() && (Rmask == 0x00FF0000) &&
   5.207 @@ -1096,18 +1015,18 @@
   5.208              swdata->Display2X = Color32DitherYV12Mod2X;
   5.209          }
   5.210          break;
   5.211 -    case SDL_YUY2_OVERLAY:
   5.212 -    case SDL_UYVY_OVERLAY:
   5.213 -    case SDL_YVYU_OVERLAY:
   5.214 -        if (display->format->BytesPerPixel == 2) {
   5.215 +    case SDL_PixelFormat_YUY2:
   5.216 +    case SDL_PixelFormat_UYVY:
   5.217 +    case SDL_PixelFormat_YVYU:
   5.218 +        if (SDL_BYTESPERPIXEL(target_format) == 2) {
   5.219              swdata->Display1X = Color16DitherYUY2Mod1X;
   5.220              swdata->Display2X = Color16DitherYUY2Mod2X;
   5.221          }
   5.222 -        if (display->format->BytesPerPixel == 3) {
   5.223 +        if (SDL_BYTESPERPIXEL(target_format) == 3) {
   5.224              swdata->Display1X = Color24DitherYUY2Mod1X;
   5.225              swdata->Display2X = Color24DitherYUY2Mod2X;
   5.226          }
   5.227 -        if (display->format->BytesPerPixel == 4) {
   5.228 +        if (SDL_BYTESPERPIXEL(target_format) == 4) {
   5.229              swdata->Display1X = Color32DitherYUY2Mod1X;
   5.230              swdata->Display2X = Color32DitherYUY2Mod2X;
   5.231          }
   5.232 @@ -1117,28 +1036,88 @@
   5.233          break;
   5.234      }
   5.235  
   5.236 +    if (swdata->display) {
   5.237 +        SDL_FreeSurface(swdata->display);
   5.238 +        swdata->display = NULL;
   5.239 +    }
   5.240 +    return 0;
   5.241 +}
   5.242 +
   5.243 +SDL_SW_YUVTexture *
   5.244 +SDL_SW_CreateYUVTexture(SDL_Texture * texture)
   5.245 +{
   5.246 +    SDL_SW_YUVTexture *swdata;
   5.247 +    int *Cr_r_tab;
   5.248 +    int *Cr_g_tab;
   5.249 +    int *Cb_g_tab;
   5.250 +    int *Cb_b_tab;
   5.251 +    int i;
   5.252 +    int CR, CB;
   5.253 +
   5.254 +    swdata = (SDL_SW_YUVTexture *) SDL_malloc(sizeof(*swdata));
   5.255 +    if (!swdata) {
   5.256 +        SDL_OutOfMemory();
   5.257 +        return NULL;
   5.258 +    }
   5.259 +    SDL_zerop(swdata);
   5.260 +
   5.261 +    switch (texture->format) {
   5.262 +    case SDL_PixelFormat_YV12:
   5.263 +    case SDL_PixelFormat_IYUV:
   5.264 +    case SDL_PixelFormat_YUY2:
   5.265 +    case SDL_PixelFormat_UYVY:
   5.266 +    case SDL_PixelFormat_YVYU:
   5.267 +        break;
   5.268 +    default:
   5.269 +        SDL_SetError("Unsupported YUV format");
   5.270 +        return NULL;
   5.271 +    }
   5.272 +
   5.273 +    swdata->texture = texture;
   5.274 +    swdata->target_format = SDL_PixelFormat_Unknown;
   5.275 +    swdata->pixels = (Uint8 *) SDL_malloc(texture->w * texture->h * 2);
   5.276 +    swdata->colortab = (int *) SDL_malloc(4 * 256 * sizeof(int));
   5.277 +    swdata->rgb_2_pix = (Uint32 *) SDL_malloc(3 * 768 * sizeof(Uint32));
   5.278 +    if (!swdata->pixels || !swdata->colortab || !swdata->rgb_2_pix) {
   5.279 +        SDL_OutOfMemory();
   5.280 +        SDL_SW_DestroyYUVTexture(swdata);
   5.281 +        return NULL;
   5.282 +    }
   5.283 +
   5.284 +    /* Generate the tables for the display surface */
   5.285 +    Cr_r_tab = &swdata->colortab[0 * 256];
   5.286 +    Cr_g_tab = &swdata->colortab[1 * 256];
   5.287 +    Cb_g_tab = &swdata->colortab[2 * 256];
   5.288 +    Cb_b_tab = &swdata->colortab[3 * 256];
   5.289 +    for (i = 0; i < 256; i++) {
   5.290 +        /* Gamma correction (luminescence table) and chroma correction
   5.291 +           would be done here.  See the Berkeley mpeg_play sources.
   5.292 +         */
   5.293 +        CB = CR = (i - 128);
   5.294 +        Cr_r_tab[i] = (int) ((0.419 / 0.299) * CR);
   5.295 +        Cr_g_tab[i] = (int) (-(0.299 / 0.419) * CR);
   5.296 +        Cb_g_tab[i] = (int) (-(0.114 / 0.331) * CB);
   5.297 +        Cb_b_tab[i] = (int) ((0.587 / 0.331) * CB);
   5.298 +    }
   5.299 +
   5.300      /* Find the pitch and offset values for the overlay */
   5.301 -    overlay->pitches = swdata->pitches;
   5.302 -    overlay->pixels = swdata->planes;
   5.303 -    switch (format) {
   5.304 -    case SDL_YV12_OVERLAY:
   5.305 -    case SDL_IYUV_OVERLAY:
   5.306 -        overlay->pitches[0] = overlay->w;
   5.307 -        overlay->pitches[1] = overlay->pitches[0] / 2;
   5.308 -        overlay->pitches[2] = overlay->pitches[0] / 2;
   5.309 -        overlay->pixels[0] = swdata->pixels;
   5.310 -        overlay->pixels[1] = overlay->pixels[0] +
   5.311 -            overlay->pitches[0] * overlay->h;
   5.312 -        overlay->pixels[2] = overlay->pixels[1] +
   5.313 -            overlay->pitches[1] * overlay->h / 2;
   5.314 -        overlay->planes = 3;
   5.315 +    switch (texture->format) {
   5.316 +    case SDL_PixelFormat_YV12:
   5.317 +    case SDL_PixelFormat_IYUV:
   5.318 +        swdata->pitches[0] = texture->w;
   5.319 +        swdata->pitches[1] = swdata->pitches[0] / 2;
   5.320 +        swdata->pitches[2] = swdata->pitches[0] / 2;
   5.321 +        swdata->planes[0] = swdata->pixels;
   5.322 +        swdata->planes[1] =
   5.323 +            swdata->planes[0] + swdata->pitches[0] * texture->h;
   5.324 +        swdata->planes[2] =
   5.325 +            swdata->planes[1] + swdata->pitches[1] * texture->h / 2;
   5.326          break;
   5.327 -    case SDL_YUY2_OVERLAY:
   5.328 -    case SDL_UYVY_OVERLAY:
   5.329 -    case SDL_YVYU_OVERLAY:
   5.330 -        overlay->pitches[0] = overlay->w * 2;
   5.331 -        overlay->pixels[0] = swdata->pixels;
   5.332 -        overlay->planes = 1;
   5.333 +    case SDL_PixelFormat_YUY2:
   5.334 +    case SDL_PixelFormat_UYVY:
   5.335 +    case SDL_PixelFormat_YVYU:
   5.336 +        swdata->pitches[0] = texture->w * 2;
   5.337 +        swdata->planes[0] = swdata->pixels;
   5.338          break;
   5.339      default:
   5.340          /* We should never get here (caught above) */
   5.341 @@ -1146,146 +1125,210 @@
   5.342      }
   5.343  
   5.344      /* We're all done.. */
   5.345 -    return (overlay);
   5.346 +    return (swdata);
   5.347  }
   5.348  
   5.349  int
   5.350 -SDL_LockYUV_SW(_THIS, SDL_Overlay * overlay)
   5.351 +SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture * swdata, void **pixels,
   5.352 +                             int *pitch)
   5.353  {
   5.354 -    return (0);
   5.355 +    *pixels = swdata->planes[0];
   5.356 +    *pitch = swdata->pitches[0];
   5.357 +    return 0;
   5.358 +}
   5.359 +
   5.360 +int
   5.361 +SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect,
   5.362 +                        const void *pixels, int pitch)
   5.363 +{
   5.364 +    SDL_Texture *texture = swdata->texture;
   5.365 +
   5.366 +    switch (texture->format) {
   5.367 +    case SDL_PixelFormat_YV12:
   5.368 +    case SDL_PixelFormat_IYUV:
   5.369 +        if (rect
   5.370 +            && (rect->x != 0 || rect->y != 0 || rect->w != texture->w
   5.371 +                || rect->h != texture->h)) {
   5.372 +            SDL_SetError
   5.373 +                ("YV12 and IYUV textures only support full surface updates");
   5.374 +            return -1;
   5.375 +        }
   5.376 +        SDL_memcpy(swdata->pixels, pixels, texture->h * texture->w * 2);
   5.377 +        break;
   5.378 +    case SDL_PixelFormat_YUY2:
   5.379 +    case SDL_PixelFormat_UYVY:
   5.380 +    case SDL_PixelFormat_YVYU:
   5.381 +        {
   5.382 +            Uint8 *src, *dst;
   5.383 +            int row;
   5.384 +            size_t length;
   5.385 +
   5.386 +            src = (Uint8 *) pixels;
   5.387 +            dst =
   5.388 +                swdata->planes[0] + rect->y * swdata->pitches[0] +
   5.389 +                rect->x * 2;
   5.390 +            length = rect->w * 2;
   5.391 +            for (row = 0; row < rect->h; ++row) {
   5.392 +                SDL_memcpy(dst, src, length);
   5.393 +                src += pitch;
   5.394 +                dst += swdata->pitches[0];
   5.395 +            }
   5.396 +        }
   5.397 +        break;
   5.398 +    }
   5.399 +    return 0;
   5.400 +}
   5.401 +
   5.402 +int
   5.403 +SDL_SW_LockYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect,
   5.404 +                      int markDirty, void **pixels, int *pitch)
   5.405 +{
   5.406 +    SDL_Texture *texture = swdata->texture;
   5.407 +
   5.408 +    switch (texture->format) {
   5.409 +    case SDL_PixelFormat_YV12:
   5.410 +    case SDL_PixelFormat_IYUV:
   5.411 +        if (rect
   5.412 +            && (rect->x != 0 || rect->y != 0 || rect->w != texture->w
   5.413 +                || rect->h != texture->h)) {
   5.414 +            SDL_SetError
   5.415 +                ("YV12 and IYUV textures only support full surface locks");
   5.416 +            return -1;
   5.417 +        }
   5.418 +        break;
   5.419 +    }
   5.420 +
   5.421 +    *pixels = swdata->planes[0] + rect->y * swdata->pitches[0] + rect->x * 2;
   5.422 +    *pitch = swdata->pitches[0];
   5.423 +    return 0;
   5.424  }
   5.425  
   5.426  void
   5.427 -SDL_UnlockYUV_SW(_THIS, SDL_Overlay * overlay)
   5.428 +SDL_SW_UnlockYUVTexture(SDL_SW_YUVTexture * swdata)
   5.429  {
   5.430 -    return;
   5.431  }
   5.432  
   5.433  int
   5.434 -SDL_DisplayYUV_SW(_THIS, SDL_Overlay * overlay, SDL_Rect * src,
   5.435 -                  SDL_Rect * dst)
   5.436 +SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture * swdata, const SDL_Rect * srcrect,
   5.437 +                    Uint32 target_format, int w, int h, void *pixels,
   5.438 +                    int pitch)
   5.439  {
   5.440 -    struct private_yuvhwdata *swdata;
   5.441 +    SDL_Texture *texture = swdata->texture;
   5.442      int stretch;
   5.443      int scale_2x;
   5.444 -    SDL_Surface *display;
   5.445      Uint8 *lum, *Cr, *Cb;
   5.446 -    Uint8 *dstp;
   5.447      int mod;
   5.448  
   5.449 -    swdata = overlay->hwdata;
   5.450 +    /* Make sure we're set up to display in the desired format */
   5.451 +    if (target_format != swdata->target_format) {
   5.452 +        if (SDL_SW_SetupYUVDisplay(swdata, target_format) < 0) {
   5.453 +            return -1;
   5.454 +        }
   5.455 +    }
   5.456 +
   5.457      stretch = 0;
   5.458      scale_2x = 0;
   5.459 -    if (src->x || src->y || src->w < overlay->w || src->h < overlay->h) {
   5.460 +    if (srcrect->x || srcrect->y || srcrect->w < texture->w
   5.461 +        || srcrect->h < texture->h) {
   5.462          /* The source rectangle has been clipped.
   5.463             Using a scratch surface is easier than adding clipped
   5.464             source support to all the blitters, plus that would
   5.465             slow them down in the general unclipped case.
   5.466           */
   5.467          stretch = 1;
   5.468 -    } else if ((src->w != dst->w) || (src->h != dst->h)) {
   5.469 -        if ((dst->w == 2 * src->w) && (dst->h == 2 * src->h)) {
   5.470 +    } else if ((srcrect->w != w) || (srcrect->h != h)) {
   5.471 +        if ((w == 2 * srcrect->w) && (h == 2 * srcrect->h)) {
   5.472              scale_2x = 1;
   5.473          } else {
   5.474              stretch = 1;
   5.475          }
   5.476      }
   5.477      if (stretch) {
   5.478 +        int bpp;
   5.479 +        Uint32 Rmask, Gmask, Bmask, Amask;
   5.480 +
   5.481 +        if (swdata->display) {
   5.482 +            swdata->display->w = w;
   5.483 +            swdata->display->h = h;
   5.484 +            swdata->display->pixels = pixels;
   5.485 +            swdata->display->pitch = pitch;
   5.486 +        } else {
   5.487 +            /* This must have succeeded in SDL_SW_SetupYUVDisplay() earlier */
   5.488 +            SDL_PixelFormatEnumToMasks(target_format, &bpp, &Rmask, &Gmask,
   5.489 +                                       &Bmask, &Amask);
   5.490 +            swdata->display =
   5.491 +                SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch, Rmask,
   5.492 +                                         Gmask, Bmask, Amask);
   5.493 +            if (!swdata->display) {
   5.494 +                return (-1);
   5.495 +            }
   5.496 +        }
   5.497          if (!swdata->stretch) {
   5.498 -            display = swdata->display;
   5.499 -            swdata->stretch = SDL_CreateRGBSurface(0,
   5.500 -                                                   overlay->w,
   5.501 -                                                   overlay->h,
   5.502 -                                                   display->format->
   5.503 -                                                   BitsPerPixel,
   5.504 -                                                   display->format->
   5.505 -                                                   Rmask,
   5.506 -                                                   display->format->
   5.507 -                                                   Gmask,
   5.508 -                                                   display->format->Bmask, 0);
   5.509 +            /* This must have succeeded in SDL_SW_SetupYUVDisplay() earlier */
   5.510 +            SDL_PixelFormatEnumToMasks(target_format, &bpp, &Rmask, &Gmask,
   5.511 +                                       &Bmask, &Amask);
   5.512 +            swdata->stretch =
   5.513 +                SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask,
   5.514 +                                     Gmask, Bmask, Amask);
   5.515              if (!swdata->stretch) {
   5.516                  return (-1);
   5.517              }
   5.518          }
   5.519 -        display = swdata->stretch;
   5.520 -    } else {
   5.521 -        display = swdata->display;
   5.522 +        pixels = swdata->stretch->pixels;
   5.523 +        pitch = swdata->stretch->pitch;
   5.524      }
   5.525 -    switch (overlay->format) {
   5.526 -    case SDL_YV12_OVERLAY:
   5.527 -        lum = overlay->pixels[0];
   5.528 -        Cr = overlay->pixels[1];
   5.529 -        Cb = overlay->pixels[2];
   5.530 +    switch (texture->format) {
   5.531 +    case SDL_PixelFormat_YV12:
   5.532 +        lum = swdata->planes[0];
   5.533 +        Cr = swdata->planes[1];
   5.534 +        Cb = swdata->planes[2];
   5.535          break;
   5.536 -    case SDL_IYUV_OVERLAY:
   5.537 -        lum = overlay->pixels[0];
   5.538 -        Cr = overlay->pixels[2];
   5.539 -        Cb = overlay->pixels[1];
   5.540 +    case SDL_PixelFormat_IYUV:
   5.541 +        lum = swdata->planes[0];
   5.542 +        Cr = swdata->planes[2];
   5.543 +        Cb = swdata->planes[1];
   5.544          break;
   5.545 -    case SDL_YUY2_OVERLAY:
   5.546 -        lum = overlay->pixels[0];
   5.547 +    case SDL_PixelFormat_YUY2:
   5.548 +        lum = swdata->planes[0];
   5.549          Cr = lum + 3;
   5.550          Cb = lum + 1;
   5.551          break;
   5.552 -    case SDL_UYVY_OVERLAY:
   5.553 -        lum = overlay->pixels[0] + 1;
   5.554 +    case SDL_PixelFormat_UYVY:
   5.555 +        lum = swdata->planes[0] + 1;
   5.556          Cr = lum + 1;
   5.557          Cb = lum - 1;
   5.558          break;
   5.559 -    case SDL_YVYU_OVERLAY:
   5.560 -        lum = overlay->pixels[0];
   5.561 +    case SDL_PixelFormat_YVYU:
   5.562 +        lum = swdata->planes[0];
   5.563          Cr = lum + 1;
   5.564          Cb = lum + 3;
   5.565          break;
   5.566      default:
   5.567 -        SDL_SetError("Unsupported YUV format in blit");
   5.568 +        SDL_SetError("Unsupported YUV format in copy");
   5.569          return (-1);
   5.570      }
   5.571 -    if (SDL_MUSTLOCK(display)) {
   5.572 -        if (SDL_LockSurface(display) < 0) {
   5.573 -            return (-1);
   5.574 -        }
   5.575 +    mod = (pitch / SDL_BYTESPERPIXEL(target_format));
   5.576 +
   5.577 +    if (scale_2x) {
   5.578 +        mod -= (texture->w * 2);
   5.579 +        swdata->Display2X(swdata->colortab, swdata->rgb_2_pix,
   5.580 +                          lum, Cr, Cb, pixels, texture->h, texture->w, mod);
   5.581 +    } else {
   5.582 +        mod -= texture->w;
   5.583 +        swdata->Display1X(swdata->colortab, swdata->rgb_2_pix,
   5.584 +                          lum, Cr, Cb, pixels, texture->h, texture->w, mod);
   5.585      }
   5.586      if (stretch) {
   5.587 -        dstp = (Uint8 *) swdata->stretch->pixels;
   5.588 -    } else {
   5.589 -        dstp = (Uint8 *) display->pixels
   5.590 -            + dst->x * display->format->BytesPerPixel
   5.591 -            + dst->y * display->pitch;
   5.592 +        SDL_Rect rect = *srcrect;
   5.593 +        SDL_SoftStretch(swdata->stretch, &rect, swdata->display, NULL);
   5.594      }
   5.595 -    mod = (display->pitch / display->format->BytesPerPixel);
   5.596 -
   5.597 -    if (scale_2x) {
   5.598 -        mod -= (overlay->w * 2);
   5.599 -        swdata->Display2X(swdata->colortab, swdata->rgb_2_pix,
   5.600 -                          lum, Cr, Cb, dstp, overlay->h, overlay->w, mod);
   5.601 -    } else {
   5.602 -        mod -= overlay->w;
   5.603 -        swdata->Display1X(swdata->colortab, swdata->rgb_2_pix,
   5.604 -                          lum, Cr, Cb, dstp, overlay->h, overlay->w, mod);
   5.605 -    }
   5.606 -    if (SDL_MUSTLOCK(display)) {
   5.607 -        SDL_UnlockSurface(display);
   5.608 -    }
   5.609 -    if (stretch) {
   5.610 -        display = swdata->display;
   5.611 -        SDL_SoftStretch(swdata->stretch, src, display, dst);
   5.612 -    }
   5.613 -    SDL_UpdateRects(display, 1, dst);
   5.614 -
   5.615 -    return (0);
   5.616 +    return 0;
   5.617  }
   5.618  
   5.619  void
   5.620 -SDL_FreeYUV_SW(_THIS, SDL_Overlay * overlay)
   5.621 +SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture * swdata)
   5.622  {
   5.623 -    struct private_yuvhwdata *swdata;
   5.624 -
   5.625 -    swdata = overlay->hwdata;
   5.626      if (swdata) {
   5.627 -        if (swdata->stretch) {
   5.628 -            SDL_FreeSurface(swdata->stretch);
   5.629 -        }
   5.630          if (swdata->pixels) {
   5.631              SDL_free(swdata->pixels);
   5.632          }
   5.633 @@ -1295,9 +1338,14 @@
   5.634          if (swdata->rgb_2_pix) {
   5.635              SDL_free(swdata->rgb_2_pix);
   5.636          }
   5.637 +        if (swdata->stretch) {
   5.638 +            SDL_FreeSurface(swdata->stretch);
   5.639 +        }
   5.640 +        if (swdata->display) {
   5.641 +            SDL_FreeSurface(swdata->display);
   5.642 +        }
   5.643          SDL_free(swdata);
   5.644      }
   5.645  }
   5.646 -#endif /* TODO */
   5.647  
   5.648  /* vi: set ts=4 sw=4 expandtab: */
     6.1 --- a/src/video/SDL_yuv_sw_c.h	Sat Jun 17 06:45:14 2006 +0000
     6.2 +++ b/src/video/SDL_yuv_sw_c.h	Sun Jun 18 06:35:41 2006 +0000
     6.3 @@ -24,17 +24,21 @@
     6.4  #include "SDL_video.h"
     6.5  #include "SDL_sysvideo.h"
     6.6  
     6.7 -/* This is the software implementation of the YUV video overlay support */
     6.8 +/* This is the software implementation of the YUV texture support */
     6.9  
    6.10 -extern SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height,
    6.11 -                                     Uint32 format, SDL_Surface * display);
    6.12 +typedef struct SDL_SW_YUVTexture SDL_SW_YUVTexture;
    6.13  
    6.14 -extern int SDL_LockYUV_SW(_THIS, SDL_Overlay * overlay);
    6.15 +SDL_SW_YUVTexture *SDL_SW_CreateYUVTexture(SDL_Texture * texture);
    6.16 +int SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture * swdata, void **pixels,
    6.17 +                                 int *pitch);
    6.18 +int SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect,
    6.19 +                            const void *pixels, int pitch);
    6.20 +int SDL_SW_LockYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect,
    6.21 +                          int markDirty, void **pixels, int *pitch);
    6.22 +void SDL_SW_UnlockYUVTexture(SDL_SW_YUVTexture * swdata);
    6.23 +int SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture * swdata, const SDL_Rect * srcrect,
    6.24 +                        Uint32 target_format, int w, int h, void *pixels,
    6.25 +                        int pitch);
    6.26 +void SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture * swdata);
    6.27  
    6.28 -extern void SDL_UnlockYUV_SW(_THIS, SDL_Overlay * overlay);
    6.29 -
    6.30 -extern int SDL_DisplayYUV_SW(_THIS, SDL_Overlay * overlay, SDL_Rect * src,
    6.31 -                             SDL_Rect * dst);
    6.32 -
    6.33 -extern void SDL_FreeYUV_SW(_THIS, SDL_Overlay * overlay);
    6.34  /* vi: set ts=4 sw=4 expandtab: */