Emphasized the separation between SDL_Surface and SDL_Texture
authorSam Lantinga <slouken@libsdl.org>
Sat, 11 Aug 2007 20:54:31 +0000
changeset 2222926294b2bb4e
parent 2221 1d75c38e1e5c
child 2223 175754591a13
Emphasized the separation between SDL_Surface and SDL_Texture
- SDL_Surface is a system memory representation of pixel data
- SDL_Texture is a video memory representation of pixel data

The concept of SDL_Surface with SDL_HWSURFACE is no longer used.

Separated SDL_Texture types by usage rather than memory type
- SDL_TEXTUREACCESS_STATIC is for rarely changed pixel data,
can be placed in video memory.
- SDL_TEXTUREACCESS_STREAMING is for frequently changing pixel
data, usually placed in system memory or AGP memory.

Optimized the SDL_compat usage of the OpenGL renderer by only
using one copy of the framebuffer instead of two.
include/SDL_compat.h
include/SDL_video.h
src/SDL_compat.c
src/video/SDL_RLEaccel.c
src/video/SDL_renderer_gl.c
src/video/SDL_renderer_sw.c
src/video/SDL_surface.c
src/video/SDL_video.c
src/video/win32/SDL_d3drender.c
src/video/win32/SDL_gdirender.c
test/testsprite2.c
     1.1 --- a/include/SDL_compat.h	Sat Aug 11 20:46:24 2007 +0000
     1.2 +++ b/include/SDL_compat.h	Sat Aug 11 20:54:31 2007 +0000
     1.3 @@ -36,7 +36,7 @@
     1.4  /* *INDENT-ON* */
     1.5  #endif
     1.6  
     1.7 -#define SDL_SWSURFACE       0x00000000
     1.8 +#define SDL_SWSURFACE       0x00000000  /* Not used */
     1.9  #define SDL_ANYFORMAT       0x00100000
    1.10  #define SDL_HWPALETTE       0x00200000
    1.11  #define SDL_DOUBLEBUF       0x00400000
    1.12 @@ -44,6 +44,7 @@
    1.13  #define SDL_RESIZABLE       0x01000000
    1.14  #define SDL_NOFRAME         0x02000000
    1.15  #define SDL_OPENGL          0x04000000
    1.16 +#define SDL_HWSURFACE       0x08000001  /* Not used */
    1.17  #define SDL_ASYNCBLIT       0x08000000  /* Not used */
    1.18  #define SDL_HWACCEL         0x08000000  /* Not used */
    1.19  
     2.1 --- a/include/SDL_video.h	Sat Aug 11 20:46:24 2007 +0000
     2.2 +++ b/include/SDL_video.h	Sat Aug 11 20:54:31 2007 +0000
     2.3 @@ -204,8 +204,8 @@
     2.4   */
     2.5  typedef enum
     2.6  {
     2.7 -    SDL_TEXTUREACCESS_LOCAL,    /**< Lockable system memory */
     2.8 -    SDL_TEXTUREACCESS_REMOTE    /**< Unlockable video memory */
     2.9 +    SDL_TEXTUREACCESS_STATIC,    /**< Changes rarely, not lockable */
    2.10 +    SDL_TEXTUREACCESS_STREAMING  /**< Changes frequently, lockable */
    2.11  } SDL_TextureAccess;
    2.12  
    2.13  /**
    2.14 @@ -264,15 +264,14 @@
    2.15  
    2.16  /* These are the currently supported flags for the SDL_surface */
    2.17  /* Used internally (read-only) */
    2.18 -#define SDL_HWSURFACE       0x00000001  /* Surface represents a texture */
    2.19 -#define SDL_PREALLOC        0x00000002  /* Surface uses preallocated memory */
    2.20 +#define SDL_PREALLOC        0x00000001  /* Surface uses preallocated memory */
    2.21  #define SDL_SRCALPHA        0x00000004  /* Blit uses source alpha blending */
    2.22  #define SDL_SRCCOLORKEY     0x00000008  /* Blit uses a source color key */
    2.23  #define SDL_RLEACCELOK      0x00000010  /* Private flag */
    2.24  #define SDL_RLEACCEL        0x00000020  /* Surface is RLE encoded */
    2.25  
    2.26  /* Evaluates to true if the surface needs to be locked before access */
    2.27 -#define SDL_MUSTLOCK(S)	(((S)->flags & (SDL_HWSURFACE|SDL_RLEACCEL)) != 0)
    2.28 +#define SDL_MUSTLOCK(S)	(((S)->flags & SDL_RLEACCEL) != 0)
    2.29  
    2.30  /* This structure should be treated as read-only, except for 'pixels',
    2.31     which, if not NULL, contains the raw pixel data for the surface.
    2.32 @@ -288,9 +287,6 @@
    2.33      /* Application data associated with the surfade */
    2.34      void *userdata;             /* Read-write */
    2.35  
    2.36 -    /* texture associated with the surface, if any */
    2.37 -    SDL_TextureID textureID;    /* Read-only */
    2.38 -
    2.39      /* information needed for surfaces requiring locks */
    2.40      int locked;                 /* Read-only */
    2.41      void *lock_data;            /* Read-only */
    2.42 @@ -927,12 +923,11 @@
    2.43                                                          int h);
    2.44  
    2.45  /**
    2.46 - * \fn SDL_TextureID SDL_CreateTextureFromSurface(Uint32 format, int access, SDL_Surface *surface)
    2.47 + * \fn SDL_TextureID SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface *surface)
    2.48   *
    2.49   * \brief Create a texture from an existing surface.
    2.50   *
    2.51   * \param format The format of the texture, or 0 to pick an appropriate format
    2.52 - * \param access One of the enumerated values in SDL_TextureAccess
    2.53   * \param surface The surface containing pixel data used to fill the texture
    2.54   *
    2.55   * \return The created texture is returned, or 0 if no rendering context was active,  the format was unsupported, or the surface width or height were out of range.
    2.56 @@ -944,7 +939,6 @@
    2.57   */
    2.58  extern DECLSPEC SDL_TextureID SDLCALL SDL_CreateTextureFromSurface(Uint32
    2.59                                                                     format,
    2.60 -                                                                   int access,
    2.61                                                                     SDL_Surface
    2.62                                                                     * surface);
    2.63  
    2.64 @@ -970,7 +964,7 @@
    2.65   *
    2.66   * \brief Query the pixels of a texture, if the texture does not need to be locked for pixel access.
    2.67   *
    2.68 - * \param texture A texture to be queried, which was created with SDL_TEXTUREACCESS_LOCAL
    2.69 + * \param texture A texture to be queried, which was created with SDL_TEXTUREACCESS_STREAMING
    2.70   * \param pixels A pointer filled with a pointer to the pixels for the texture 
    2.71   * \param pitch A pointer filled in with the pitch of the pixel data
    2.72   *
    2.73 @@ -1155,7 +1149,7 @@
    2.74   *
    2.75   * \return 0 on success, or -1 if the texture is not valid
    2.76   *
    2.77 - * \note This is a very slow function for textures not created with SDL_TEXTUREACCESS_LOCAL.
    2.78 + * \note This is a fairly slow function.
    2.79   */
    2.80  extern DECLSPEC int SDLCALL SDL_UpdateTexture(SDL_TextureID textureID,
    2.81                                                const SDL_Rect * rect,
    2.82 @@ -1166,13 +1160,13 @@
    2.83   *
    2.84   * \brief Lock a portion of the texture for pixel access.
    2.85   *
    2.86 - * \param texture The texture to lock for access, which must have been created with SDL_TEXTUREACCESS_LOCAL.
    2.87 + * \param textureID The texture to lock for access, which was created with SDL_TEXTUREACCESS_STREAMING.
    2.88   * \param rect A pointer to the rectangle to lock for access. If the rect is NULL, the entire texture will be locked.
    2.89   * \param markDirty If this is nonzero, the locked area will be marked dirty when the texture is unlocked.
    2.90   * \param pixels This is filled in with a pointer to the locked pixels, appropriately offset by the locked area.
    2.91   * \param pitch This is filled in with the pitch of the locked pixels.
    2.92   *
    2.93 - * \return 0 on success, or -1 if the texture is not valid or was created with SDL_TEXTUREACCESS_REMOTe
    2.94 + * \return 0 on success, or -1 if the texture is not valid or was created with SDL_TEXTUREACCESS_STATIC
    2.95   *
    2.96   * \sa SDL_DirtyTexture()
    2.97   * \sa SDL_UnlockTexture()
    2.98 @@ -1197,7 +1191,9 @@
    2.99   *
   2.100   * \brief Mark the specified rectangles of the texture as dirty.
   2.101   *
   2.102 - * \note The texture must have been created with SDL_TEXTUREACCESS_LOCAL.
   2.103 + * \param textureID The texture to mark dirty, which was created with SDL_TEXTUREACCESS_STREAMING.
   2.104 + * \param numrects The number of rectangles pointed to by rects.
   2.105 + * \param rects The pointer to an array of dirty rectangles.
   2.106   *
   2.107   * \sa SDL_LockTexture()
   2.108   * \sa SDL_UnlockTexture()
   2.109 @@ -1347,8 +1343,6 @@
   2.110                                                                Uint32 Gmask,
   2.111                                                                Uint32 Bmask,
   2.112                                                                Uint32 Amask);
   2.113 -extern DECLSPEC SDL_Surface *SDLCALL
   2.114 -SDL_CreateRGBSurfaceFromTexture(SDL_TextureID textureID);
   2.115  extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface * surface);
   2.116  
   2.117  /**
     3.1 --- a/src/SDL_compat.c	Sat Aug 11 20:46:24 2007 +0000
     3.2 +++ b/src/SDL_compat.c	Sat Aug 11 20:54:31 2007 +0000
     3.3 @@ -328,6 +328,38 @@
     3.4      }
     3.5  }
     3.6  
     3.7 +static SDL_Surface *
     3.8 +CreateVideoSurface(SDL_TextureID textureID)
     3.9 +{
    3.10 +    SDL_Surface *surface;
    3.11 +    Uint32 format;
    3.12 +    int w, h;
    3.13 +    int bpp;
    3.14 +    Uint32 Rmask, Gmask, Bmask, Amask;
    3.15 +    void *pixels;
    3.16 +    int pitch;
    3.17 +
    3.18 +    if (SDL_QueryTexture(textureID, &format, NULL, &w, &h) < 0) {
    3.19 +        return NULL;
    3.20 +    }
    3.21 +
    3.22 +    if (!SDL_PixelFormatEnumToMasks
    3.23 +        (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
    3.24 +        SDL_SetError("Unknown texture format");
    3.25 +        return NULL;
    3.26 +    }
    3.27 +
    3.28 +    if (SDL_QueryTexturePixels(textureID, &pixels, &pitch) == 0) {
    3.29 +        surface =
    3.30 +            SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch, Rmask, Gmask,
    3.31 +                                     Bmask, Amask);
    3.32 +    } else {
    3.33 +        surface =
    3.34 +            SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
    3.35 +    }
    3.36 +    return surface;
    3.37 +}
    3.38 +
    3.39  SDL_Surface *
    3.40  SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
    3.41  {
    3.42 @@ -483,23 +515,23 @@
    3.43           SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD) < 0) {
    3.44          return NULL;
    3.45      }
    3.46 -    SDL_GetRenderDriverInfo(-1, &SDL_VideoRendererInfo);
    3.47 +    SDL_GetRendererInfo(&SDL_VideoRendererInfo);
    3.48  
    3.49      /* Create a texture for the screen surface */
    3.50      SDL_VideoTexture =
    3.51 -        SDL_CreateTexture(desired_format, SDL_TEXTUREACCESS_LOCAL, width,
    3.52 +        SDL_CreateTexture(desired_format, SDL_TEXTUREACCESS_STREAMING, width,
    3.53                            height);
    3.54      if (!SDL_VideoTexture) {
    3.55          SDL_VideoTexture =
    3.56 -            SDL_CreateTexture(SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_LOCAL,
    3.57 -                              width, height);
    3.58 +            SDL_CreateTexture(SDL_PIXELFORMAT_RGB888,
    3.59 +                              SDL_TEXTUREACCESS_STREAMING, width, height);
    3.60      }
    3.61      if (!SDL_VideoTexture) {
    3.62          return NULL;
    3.63      }
    3.64  
    3.65      /* Create the screen surface */
    3.66 -    SDL_VideoSurface = SDL_CreateRGBSurfaceFromTexture(SDL_VideoTexture);
    3.67 +    SDL_VideoSurface = CreateVideoSurface(SDL_VideoTexture);
    3.68      if (!SDL_VideoSurface) {
    3.69          return NULL;
    3.70      }
    3.71 @@ -518,23 +550,10 @@
    3.72      }
    3.73  
    3.74      /* Create a shadow surface if necessary */
    3.75 -    if (((bpp != SDL_VideoSurface->format->BitsPerPixel)
    3.76 -         && !(flags & SDL_ANYFORMAT))
    3.77 -        || ((SDL_VideoSurface->flags & SDL_HWSURFACE)
    3.78 -            && !(flags & SDL_HWSURFACE))) {
    3.79 -        if ((bpp == SDL_VideoSurface->format->BitsPerPixel)
    3.80 -            || (flags & SDL_ANYFORMAT)) {
    3.81 -            SDL_ShadowSurface =
    3.82 -                SDL_CreateRGBSurface(0, width, height,
    3.83 -                                     SDL_VideoSurface->format->BitsPerPixel,
    3.84 -                                     SDL_VideoSurface->format->Rmask,
    3.85 -                                     SDL_VideoSurface->format->Gmask,
    3.86 -                                     SDL_VideoSurface->format->Bmask,
    3.87 -                                     SDL_VideoSurface->format->Amask);
    3.88 -        } else {
    3.89 -            SDL_ShadowSurface =
    3.90 -                SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0);
    3.91 -        }
    3.92 +    if ((bpp != SDL_VideoSurface->format->BitsPerPixel)
    3.93 +        && !(flags & SDL_ANYFORMAT)) {
    3.94 +        SDL_ShadowSurface =
    3.95 +            SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0);
    3.96          if (!SDL_ShadowSurface) {
    3.97              return NULL;
    3.98          }
    3.99 @@ -638,8 +657,7 @@
   3.100          break;
   3.101      }
   3.102      format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
   3.103 -    flags = SDL_PublicSurface->flags & SDL_HWSURFACE;
   3.104 -    flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
   3.105 +    flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
   3.106      converted = SDL_ConvertSurface(surface, format, flags);
   3.107      SDL_FreeFormat(format);
   3.108      return converted;
   3.109 @@ -681,6 +699,22 @@
   3.110          screen = SDL_VideoSurface;
   3.111      }
   3.112      if (screen == SDL_VideoSurface) {
   3.113 +        if (screen->flags & SDL_PREALLOC) {
   3.114 +            /* The surface memory is maintained by the renderer */
   3.115 +            SDL_DirtyTexture(SDL_VideoTexture, numrects, rects);
   3.116 +        } else {
   3.117 +            /* The surface memory needs to be copied to texture */
   3.118 +            void *pixels;
   3.119 +            int pitch = screen->pitch;
   3.120 +            int psize = screen->format->BytesPerPixel;
   3.121 +            for (i = 0; i < numrects; ++i) {
   3.122 +                const SDL_Rect *rect = &rects[i];
   3.123 +                void *pixels =
   3.124 +                    (Uint8 *) screen->pixels + rect->y * pitch +
   3.125 +                    rect->x * psize;
   3.126 +                SDL_UpdateTexture(SDL_VideoTexture, rect, pixels, pitch);
   3.127 +            }
   3.128 +        }
   3.129          if (SDL_VideoRendererInfo.flags & SDL_RENDERER_PRESENTCOPY) {
   3.130              for (i = 0; i < numrects; ++i) {
   3.131                  SDL_RenderCopy(SDL_VideoTexture, &rects[i], &rects[i]);
   3.132 @@ -1174,8 +1208,7 @@
   3.133      if (SDL_MUSTLOCK(screen)) {
   3.134          SDL_UnlockSurface(screen);
   3.135      }
   3.136 -    if ((screen->flags & SDL_SCREEN_SURFACE) &&
   3.137 -        !(screen->flags & SDL_HWSURFACE)) {
   3.138 +    if (screen->flags & SDL_SCREEN_SURFACE) {
   3.139          SDL_VideoDevice *_this = SDL_GetVideoDevice();
   3.140          SDL_Window *window;
   3.141          SDL_Rect area;
   3.142 @@ -1263,8 +1296,7 @@
   3.143      if (SDL_MUSTLOCK(screen)) {
   3.144          SDL_UnlockSurface(screen);
   3.145      }
   3.146 -    if ((screen->flags & SDL_SCREEN_SURFACE) &&
   3.147 -        !(screen->flags & SDL_HWSURFACE)) {
   3.148 +    if (screen->flags & SDL_SCREEN_SURFACE) {
   3.149          SDL_VideoDevice *_this = SDL_GetVideoDevice();
   3.150          SDL_Window *window;
   3.151          SDL_Rect area;
   3.152 @@ -1385,7 +1417,7 @@
   3.153      }
   3.154  
   3.155      overlay->hwdata->textureID =
   3.156 -        SDL_CreateTexture(texture_format, SDL_TEXTUREACCESS_LOCAL, w, h);
   3.157 +        SDL_CreateTexture(texture_format, SDL_TEXTUREACCESS_STREAMING, w, h);
   3.158      if (!overlay->hwdata->textureID) {
   3.159          SDL_FreeYUVOverlay(overlay);
   3.160          return NULL;
     4.1 --- a/src/video/SDL_RLEaccel.c	Sat Aug 11 20:46:24 2007 +0000
     4.2 +++ b/src/video/SDL_RLEaccel.c	Sat Aug 11 20:54:31 2007 +0000
     4.3 @@ -1618,7 +1618,7 @@
     4.4  #undef ADD_TRANSL_COUNTS
     4.5  
     4.6      /* Now that we have it encoded, release the original pixels */
     4.7 -    if (!(surface->flags & SDL_PREALLOC) && !(surface->flags & SDL_HWSURFACE)) {
     4.8 +    if (!(surface->flags & SDL_PREALLOC)) {
     4.9          SDL_free(surface->pixels);
    4.10          surface->pixels = NULL;
    4.11      }
    4.12 @@ -1783,7 +1783,7 @@
    4.13  #undef ADD_COUNTS
    4.14  
    4.15      /* Now that we have it encoded, release the original pixels */
    4.16 -    if (!(surface->flags & SDL_PREALLOC) && !(surface->flags & SDL_HWSURFACE)) {
    4.17 +    if (!(surface->flags & SDL_PREALLOC)) {
    4.18          SDL_free(surface->pixels);
    4.19          surface->pixels = NULL;
    4.20      }
    4.21 @@ -1934,8 +1934,7 @@
    4.22      if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
    4.23          surface->flags &= ~SDL_RLEACCEL;
    4.24  
    4.25 -        if (recode && !(surface->flags & SDL_PREALLOC)
    4.26 -            && !(surface->flags & SDL_HWSURFACE)) {
    4.27 +        if (recode && !(surface->flags & SDL_PREALLOC)) {
    4.28              if ((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
    4.29                  SDL_Rect full;
    4.30                  unsigned alpha_flag;
     5.1 --- a/src/video/SDL_renderer_gl.c	Sat Aug 11 20:46:24 2007 +0000
     5.2 +++ b/src/video/SDL_renderer_gl.c	Sat Aug 11 20:54:31 2007 +0000
     5.3 @@ -38,6 +38,9 @@
     5.4  static int GL_ActivateRenderer(SDL_Renderer * renderer);
     5.5  static int GL_DisplayModeChanged(SDL_Renderer * renderer);
     5.6  static int GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
     5.7 +static int GL_QueryTexturePixels(SDL_Renderer * renderer,
     5.8 +                                 SDL_Texture * texture, void **pixels,
     5.9 +                                 int *pitch);
    5.10  static int GL_SetTexturePalette(SDL_Renderer * renderer,
    5.11                                  SDL_Texture * texture,
    5.12                                  const SDL_Color * colors, int firstcolor,
    5.13 @@ -245,6 +248,7 @@
    5.14      renderer->ActivateRenderer = GL_ActivateRenderer;
    5.15      renderer->DisplayModeChanged = GL_DisplayModeChanged;
    5.16      renderer->CreateTexture = GL_CreateTexture;
    5.17 +    renderer->QueryTexturePixels = GL_QueryTexturePixels;
    5.18      renderer->SetTexturePalette = GL_SetTexturePalette;
    5.19      renderer->GetTexturePalette = GL_GetTexturePalette;
    5.20      renderer->SetTextureColorMod = GL_SetTextureColorMod;
    5.21 @@ -492,6 +496,16 @@
    5.22          SDL_memset(data->palette, 0xFF, 3 * 256 * sizeof(Uint8));
    5.23      }
    5.24  
    5.25 +    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
    5.26 +        data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
    5.27 +        data->pixels = SDL_malloc(texture->h * data->pitch);
    5.28 +        if (!data->pixels) {
    5.29 +            SDL_OutOfMemory();
    5.30 +            SDL_free(data);
    5.31 +            return -1;
    5.32 +        }
    5.33 +    }
    5.34 +
    5.35      texture->driverdata = data;
    5.36  
    5.37      renderdata->glGetError();
    5.38 @@ -523,6 +537,17 @@
    5.39  }
    5.40  
    5.41  static int
    5.42 +GL_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
    5.43 +                      void **pixels, int *pitch)
    5.44 +{
    5.45 +    GL_TextureData *data = (GL_TextureData *) texture->driverdata;
    5.46 +
    5.47 +    *pixels = data->pixels;
    5.48 +    *pitch = data->pitch;
    5.49 +    return 0;
    5.50 +}
    5.51 +
    5.52 +static int
    5.53  GL_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
    5.54                       const SDL_Color * colors, int firstcolor, int ncolors)
    5.55  {
    5.56 @@ -661,15 +686,6 @@
    5.57  {
    5.58      GL_TextureData *data = (GL_TextureData *) texture->driverdata;
    5.59  
    5.60 -    if (!data->pixels) {
    5.61 -        data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
    5.62 -        data->pixels = SDL_malloc(texture->h * data->pitch);
    5.63 -        if (!data->pixels) {
    5.64 -            SDL_OutOfMemory();
    5.65 -            return -1;
    5.66 -        }
    5.67 -    }
    5.68 -
    5.69      if (markDirty) {
    5.70          SDL_AddDirtyRect(&data->dirty, rect);
    5.71      }
     6.1 --- a/src/video/SDL_renderer_sw.c	Sat Aug 11 20:46:24 2007 +0000
     6.2 +++ b/src/video/SDL_renderer_sw.c	Sat Aug 11 20:54:31 2007 +0000
     6.3 @@ -125,7 +125,7 @@
     6.4      }
     6.5  
     6.6      texture->format = format;
     6.7 -    texture->access = SDL_TEXTUREACCESS_LOCAL;
     6.8 +    texture->access = SDL_TEXTUREACCESS_STREAMING;
     6.9      texture->w = w;
    6.10      texture->h = h;
    6.11      texture->renderer = renderer;
     7.1 --- a/src/video/SDL_surface.c	Sat Aug 11 20:46:24 2007 +0000
     7.2 +++ b/src/video/SDL_surface.c	Sat Aug 11 20:54:31 2007 +0000
     7.3 @@ -170,62 +170,11 @@
     7.4      return surface;
     7.5  }
     7.6  
     7.7 -SDL_Surface *
     7.8 -SDL_CreateRGBSurfaceFromTexture(SDL_TextureID textureID)
     7.9 -{
    7.10 -    SDL_Surface *surface;
    7.11 -    Uint32 format;
    7.12 -    int w, h;
    7.13 -    int bpp;
    7.14 -    Uint32 Rmask, Gmask, Bmask, Amask;
    7.15 -    void *pixels;
    7.16 -    int pitch;
    7.17 -
    7.18 -    if (SDL_QueryTexture(textureID, &format, NULL, &w, &h) < 0) {
    7.19 -        return NULL;
    7.20 -    }
    7.21 -
    7.22 -    if (!SDL_PixelFormatEnumToMasks
    7.23 -        (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
    7.24 -        SDL_SetError("Unknown texture format");
    7.25 -        return NULL;
    7.26 -    }
    7.27 -
    7.28 -    if (SDL_QueryTexturePixels(textureID, &pixels, &pitch) == 0) {
    7.29 -        surface =
    7.30 -            SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch, Rmask, Gmask,
    7.31 -                                     Bmask, Amask);
    7.32 -    } else {
    7.33 -        surface =
    7.34 -            SDL_CreateRGBSurface(0, 0, 0, bpp, Rmask, Gmask, Bmask, Amask);
    7.35 -        if (surface) {
    7.36 -            surface->flags |= SDL_HWSURFACE;
    7.37 -            surface->w = w;
    7.38 -            surface->h = h;
    7.39 -            surface->pitch = SDL_CalculatePitch(surface);
    7.40 -            SDL_SetClipRect(surface, NULL);
    7.41 -        }
    7.42 -    }
    7.43 -    if (surface) {
    7.44 -        surface->textureID = textureID;
    7.45 -    }
    7.46 -
    7.47 -    return surface;
    7.48 -}
    7.49 -
    7.50  static int
    7.51  SDL_SurfacePaletteChanged(void *userdata, SDL_Palette * palette)
    7.52  {
    7.53      SDL_Surface *surface = (SDL_Surface *) userdata;
    7.54  
    7.55 -    if (surface->textureID) {
    7.56 -        if (SDL_SetTexturePalette
    7.57 -            (surface->textureID, palette->colors, 0, palette->ncolors) < 0) {
    7.58 -            SDL_GetTexturePalette(surface->textureID, palette->colors, 0,
    7.59 -                                  palette->ncolors);
    7.60 -            return -1;
    7.61 -        }
    7.62 -    }
    7.63      SDL_FormatChanged(surface);
    7.64  
    7.65      return 0;
    7.66 @@ -627,74 +576,9 @@
    7.67                  row += dst->pitch;
    7.68              }
    7.69          } else {
    7.70 -#ifdef __powerpc__
    7.71 -            /*
    7.72 -             * SDL_memset() on PPC (both glibc and codewarrior) uses
    7.73 -             * the dcbz (Data Cache Block Zero) instruction, which
    7.74 -             * causes an alignment exception if the destination is
    7.75 -             * uncachable, so only use it on software surfaces
    7.76 -             */
    7.77 -            if (dst->flags & SDL_HWSURFACE) {
    7.78 -                if (dstrect->w >= 8) {
    7.79 -                    /*
    7.80 -                     * 64-bit stores are probably most
    7.81 -                     * efficient to uncached video memory
    7.82 -                     */
    7.83 -                    double fill;
    7.84 -                    SDL_memset(&fill, color, (sizeof fill));
    7.85 -                    for (y = dstrect->h; y; y--) {
    7.86 -                        Uint8 *d = row;
    7.87 -                        unsigned n = x;
    7.88 -                        unsigned nn;
    7.89 -                        Uint8 c = color;
    7.90 -                        double f = fill;
    7.91 -                        while ((unsigned long) d & (sizeof(double) - 1)) {
    7.92 -                            *d++ = c;
    7.93 -                            n--;
    7.94 -                        }
    7.95 -                        nn = n / (sizeof(double) * 4);
    7.96 -                        while (nn) {
    7.97 -                            ((double *) d)[0] = f;
    7.98 -                            ((double *) d)[1] = f;
    7.99 -                            ((double *) d)[2] = f;
   7.100 -                            ((double *) d)[3] = f;
   7.101 -                            d += 4 * sizeof(double);
   7.102 -                            nn--;
   7.103 -                        }
   7.104 -                        n &= ~(sizeof(double) * 4 - 1);
   7.105 -                        nn = n / sizeof(double);
   7.106 -                        while (nn) {
   7.107 -                            *(double *) d = f;
   7.108 -                            d += sizeof(double);
   7.109 -                            nn--;
   7.110 -                        }
   7.111 -                        n &= ~(sizeof(double) - 1);
   7.112 -                        while (n) {
   7.113 -                            *d++ = c;
   7.114 -                            n--;
   7.115 -                        }
   7.116 -                        row += dst->pitch;
   7.117 -                    }
   7.118 -                } else {
   7.119 -                    /* narrow boxes */
   7.120 -                    for (y = dstrect->h; y; y--) {
   7.121 -                        Uint8 *d = row;
   7.122 -                        Uint8 c = color;
   7.123 -                        int n = x;
   7.124 -                        while (n) {
   7.125 -                            *d++ = c;
   7.126 -                            n--;
   7.127 -                        }
   7.128 -                        row += dst->pitch;
   7.129 -                    }
   7.130 -                }
   7.131 -            } else
   7.132 -#endif /* __powerpc__ */
   7.133 -            {
   7.134 -                for (y = dstrect->h; y; y--) {
   7.135 -                    SDL_memset(row, color, x);
   7.136 -                    row += dst->pitch;
   7.137 -                }
   7.138 +            for (y = dstrect->h; y; y--) {
   7.139 +                SDL_memset(row, color, x);
   7.140 +                row += dst->pitch;
   7.141              }
   7.142          }
   7.143      } else {
   7.144 @@ -753,13 +637,6 @@
   7.145  {
   7.146      if (!surface->locked) {
   7.147          /* Perform the lock */
   7.148 -        if (surface->flags & SDL_HWSURFACE) {
   7.149 -            if (SDL_LockTexture
   7.150 -                (surface->textureID, NULL, 1, &surface->pixels,
   7.151 -                 &surface->pitch) < 0) {
   7.152 -                return (-1);
   7.153 -            }
   7.154 -        }
   7.155          if (surface->flags & SDL_RLEACCEL) {
   7.156              SDL_UnRLESurface(surface, 1);
   7.157              surface->flags |= SDL_RLEACCEL;     /* save accel'd state */
   7.158 @@ -784,11 +661,6 @@
   7.159          return;
   7.160      }
   7.161  
   7.162 -    /* Unlock hardware or accelerated surfaces */
   7.163 -    if (surface->flags & SDL_HWSURFACE) {
   7.164 -        SDL_UnlockTexture(surface->textureID);
   7.165 -    }
   7.166 -
   7.167      /* Update RLE encoded surface with new data */
   7.168      if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
   7.169          surface->flags &= ~SDL_RLEACCEL;        /* stop lying */
   7.170 @@ -928,11 +800,6 @@
   7.171          SDL_FreeBlitMap(surface->map);
   7.172          surface->map = NULL;
   7.173      }
   7.174 -    /* Should we destroy the texture too?
   7.175 -       if (surface->textureID) {
   7.176 -       SDL_DestroyTexture(surface->textureID);
   7.177 -       }
   7.178 -     */
   7.179      if (surface->pixels && ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC)) {
   7.180          SDL_free(surface->pixels);
   7.181      }
     8.1 --- a/src/video/SDL_video.c	Sat Aug 11 20:46:24 2007 +0000
     8.2 +++ b/src/video/SDL_video.c	Sat Aug 11 20:54:31 2007 +0000
     8.3 @@ -1532,14 +1532,11 @@
     8.4  }
     8.5  
     8.6  SDL_TextureID
     8.7 -SDL_CreateTextureFromSurface(Uint32 format, int access, SDL_Surface * surface)
     8.8 +SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
     8.9  {
    8.10      SDL_TextureID textureID;
    8.11      Uint32 surface_flags = surface->flags;
    8.12      SDL_PixelFormat *fmt = surface->format;
    8.13 -    Uint8 alpha;
    8.14 -    SDL_Rect bounds;
    8.15 -    SDL_Surface dst;
    8.16      int bpp;
    8.17      Uint32 Rmask, Gmask, Bmask, Amask;
    8.18  
    8.19 @@ -1576,23 +1573,41 @@
    8.20          }
    8.21      }
    8.22  
    8.23 -    textureID = SDL_CreateTexture(format, access, surface->w, surface->h);
    8.24 +    textureID =
    8.25 +        SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w,
    8.26 +                          surface->h);
    8.27      if (!textureID) {
    8.28          return 0;
    8.29      }
    8.30  
    8.31 -    /* Set up a destination surface for the texture update */
    8.32 -    SDL_zero(dst);
    8.33 -    dst.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
    8.34 -    if (!dst.format) {
    8.35 -        SDL_DestroyTexture(textureID);
    8.36 -        return 0;
    8.37 -    }
    8.38 -    dst.w = surface->w;
    8.39 -    dst.h = surface->h;
    8.40 -    if (SDL_LockTexture(textureID, NULL, 1, &dst.pixels, &dst.pitch) == 0) {
    8.41 -        dst.flags |= SDL_PREALLOC;
    8.42 +    if (bpp == fmt->BitsPerPixel && Rmask == fmt->Rmask && Gmask == fmt->Gmask
    8.43 +        && Bmask == fmt->Bmask && Amask == fmt->Amask) {
    8.44 +        if (SDL_MUSTLOCK(surface)) {
    8.45 +            if (SDL_LockSurface(surface) < 0) {
    8.46 +                SDL_DestroyTexture(textureID);
    8.47 +                return 0;
    8.48 +            }
    8.49 +            SDL_UpdateTexture(textureID, NULL, surface->pixels,
    8.50 +                              surface->pitch);
    8.51 +            SDL_UnlockSurface(surface);
    8.52 +        } else {
    8.53 +            SDL_UpdateTexture(textureID, NULL, surface->pixels,
    8.54 +                              surface->pitch);
    8.55 +        }
    8.56      } else {
    8.57 +        Uint8 alpha;
    8.58 +        SDL_Rect bounds;
    8.59 +        SDL_Surface dst;
    8.60 +
    8.61 +        /* Set up a destination surface for the texture update */
    8.62 +        SDL_zero(dst);
    8.63 +        dst.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
    8.64 +        if (!dst.format) {
    8.65 +            SDL_DestroyTexture(textureID);
    8.66 +            return 0;
    8.67 +        }
    8.68 +        dst.w = surface->w;
    8.69 +        dst.h = surface->h;
    8.70          dst.pitch = SDL_CalculatePitch(&dst);
    8.71          dst.pixels = SDL_malloc(dst.h * dst.pitch);
    8.72          if (!dst.pixels) {
    8.73 @@ -1601,76 +1616,72 @@
    8.74              SDL_OutOfMemory();
    8.75              return 0;
    8.76          }
    8.77 -    }
    8.78  
    8.79 -    /* Copy the palette if any */
    8.80 -    if (SDL_ISPIXELFORMAT_INDEXED(format)) {
    8.81 -        if (fmt->palette) {
    8.82 -            SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
    8.83 -                                  fmt->palette->ncolors);
    8.84 -            SDL_SetSurfacePalette(&dst, fmt->palette);
    8.85 -        } else {
    8.86 -            dst.format->palette =
    8.87 -                SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
    8.88 -            if (!dst.format->palette) {
    8.89 -                SDL_DestroyTexture(textureID);
    8.90 -                SDL_FreeFormat(dst.format);
    8.91 -                return 0;
    8.92 +        /* Copy the palette if any */
    8.93 +        if (SDL_ISPIXELFORMAT_INDEXED(format)) {
    8.94 +            if (fmt->palette) {
    8.95 +                SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
    8.96 +                                      fmt->palette->ncolors);
    8.97 +                SDL_SetSurfacePalette(&dst, fmt->palette);
    8.98 +            } else {
    8.99 +                dst.format->palette =
   8.100 +                    SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
   8.101 +                if (!dst.format->palette) {
   8.102 +                    SDL_DestroyTexture(textureID);
   8.103 +                    SDL_FreeFormat(dst.format);
   8.104 +                    return 0;
   8.105 +                }
   8.106 +                SDL_DitherColors(dst.format->palette->colors,
   8.107 +                                 SDL_BITSPERPIXEL(format));
   8.108              }
   8.109 -            SDL_DitherColors(dst.format->palette->colors,
   8.110 -                             SDL_BITSPERPIXEL(format));
   8.111          }
   8.112 -    }
   8.113  
   8.114 -    /* Make the texture transparent if the surface has colorkey */
   8.115 -    if (surface_flags & SDL_SRCCOLORKEY) {
   8.116 -        int row;
   8.117 -        int length = dst.w * dst.format->BytesPerPixel;
   8.118 -        Uint8 *p = (Uint8 *) dst.pixels;
   8.119 -        for (row = 0; row < dst.h; ++row) {
   8.120 -            SDL_memset(p, 0, length);
   8.121 -            p += dst.pitch;
   8.122 +        /* Make the texture transparent if the surface has colorkey */
   8.123 +        if (surface_flags & SDL_SRCCOLORKEY) {
   8.124 +            int row;
   8.125 +            int length = dst.w * dst.format->BytesPerPixel;
   8.126 +            Uint8 *p = (Uint8 *) dst.pixels;
   8.127 +            for (row = 0; row < dst.h; ++row) {
   8.128 +                SDL_memset(p, 0, length);
   8.129 +                p += dst.pitch;
   8.130 +            }
   8.131          }
   8.132 -    }
   8.133  
   8.134 -    /* Copy over the alpha channel */
   8.135 -    if (surface_flags & SDL_SRCALPHA) {
   8.136 -        if (fmt->Amask) {
   8.137 -            surface->flags &= ~SDL_SRCALPHA;
   8.138 -        } else {
   8.139 -            /* FIXME: Need to make sure the texture has an alpha channel
   8.140 -             *        and copy 'alpha' into the texture alpha channel.
   8.141 -             */
   8.142 -            alpha = surface->format->alpha;
   8.143 -            SDL_SetAlpha(surface, 0, 0);
   8.144 +        /* Copy over the alpha channel */
   8.145 +        if (surface_flags & SDL_SRCALPHA) {
   8.146 +            if (fmt->Amask) {
   8.147 +                surface->flags &= ~SDL_SRCALPHA;
   8.148 +            } else {
   8.149 +                /* FIXME: Need to make sure the texture has an alpha channel
   8.150 +                 *        and copy 'alpha' into the texture alpha channel.
   8.151 +                 */
   8.152 +                alpha = surface->format->alpha;
   8.153 +                SDL_SetAlpha(surface, 0, 0);
   8.154 +            }
   8.155          }
   8.156 -    }
   8.157  
   8.158 -    /* Copy over the image data */
   8.159 -    bounds.x = 0;
   8.160 -    bounds.y = 0;
   8.161 -    bounds.w = surface->w;
   8.162 -    bounds.h = surface->h;
   8.163 -    SDL_LowerBlit(surface, &bounds, &dst, &bounds);
   8.164 +        /* Copy over the image data */
   8.165 +        bounds.x = 0;
   8.166 +        bounds.y = 0;
   8.167 +        bounds.w = surface->w;
   8.168 +        bounds.h = surface->h;
   8.169 +        SDL_LowerBlit(surface, &bounds, &dst, &bounds);
   8.170  
   8.171 -    /* Clean up the original surface */
   8.172 -    if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
   8.173 -        Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
   8.174 -        if (fmt->Amask) {
   8.175 -            surface->flags |= SDL_SRCALPHA;
   8.176 -        } else {
   8.177 -            SDL_SetAlpha(surface, aflags, alpha);
   8.178 +        /* Clean up the original surface */
   8.179 +        if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
   8.180 +            Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
   8.181 +            if (fmt->Amask) {
   8.182 +                surface->flags |= SDL_SRCALPHA;
   8.183 +            } else {
   8.184 +                SDL_SetAlpha(surface, aflags, alpha);
   8.185 +            }
   8.186          }
   8.187 -    }
   8.188  
   8.189 -    /* Update the texture */
   8.190 -    if (dst.flags & SDL_PREALLOC) {
   8.191 -        SDL_UnlockTexture(textureID);
   8.192 -    } else {
   8.193 +        /* Update the texture */
   8.194          SDL_UpdateTexture(textureID, NULL, dst.pixels, dst.pitch);
   8.195          SDL_free(dst.pixels);
   8.196 +        SDL_FreeFormat(dst.format);
   8.197      }
   8.198 -    SDL_FreeFormat(dst.format);
   8.199  
   8.200      return textureID;
   8.201  }
   8.202 @@ -1967,6 +1978,10 @@
   8.203      if (!texture) {
   8.204          return -1;
   8.205      }
   8.206 +    if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
   8.207 +        SDL_SetError("SDL_LockTexture(): texture must be streaming");
   8.208 +        return -1;
   8.209 +    }
   8.210  
   8.211      renderer = texture->renderer;
   8.212      if (!renderer->LockTexture) {
   8.213 @@ -1994,6 +2009,9 @@
   8.214      if (!texture) {
   8.215          return;
   8.216      }
   8.217 +    if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
   8.218 +        return;
   8.219 +    }
   8.220  
   8.221      renderer = texture->renderer;
   8.222      if (!renderer->UnlockTexture) {
   8.223 @@ -2012,6 +2030,9 @@
   8.224      if (!texture) {
   8.225          return;
   8.226      }
   8.227 +    if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
   8.228 +        return;
   8.229 +    }
   8.230  
   8.231      renderer = texture->renderer;
   8.232      if (!renderer->DirtyTexture) {
     9.1 --- a/src/video/win32/SDL_d3drender.c	Sat Aug 11 20:46:24 2007 +0000
     9.2 +++ b/src/video/win32/SDL_d3drender.c	Sat Aug 11 20:54:31 2007 +0000
     9.3 @@ -459,7 +459,6 @@
     9.4      SDL_Window *window = SDL_GetWindowFromID(renderer->window);
     9.5      SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
     9.6      D3D_TextureData *data;
     9.7 -    D3DPOOL pool;
     9.8      HRESULT result;
     9.9  
    9.10      data = (D3D_TextureData *) SDL_calloc(1, sizeof(*data));
    9.11 @@ -470,22 +469,11 @@
    9.12  
    9.13      texture->driverdata = data;
    9.14  
    9.15 -#if 1
    9.16 -    /* FIXME: Do we want non-managed textures?
    9.17 -       They need to be freed on device reset and then reloaded by the app...
    9.18 -     */
    9.19 -    texture->access = SDL_TEXTUREACCESS_LOCAL;
    9.20 -#endif
    9.21 -    if (texture->access == SDL_TEXTUREACCESS_LOCAL) {
    9.22 -        pool = D3DPOOL_MANAGED;
    9.23 -    } else {
    9.24 -        pool = D3DPOOL_DEFAULT;
    9.25 -    }
    9.26      result =
    9.27          IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
    9.28                                         texture->h, 1, 0,
    9.29                                         PixelFormatToD3DFMT(texture->format),
    9.30 -                                       pool, &data->texture, NULL);
    9.31 +                                       D3DPOOL_MANAGED, &data->texture, NULL);
    9.32      if (FAILED(result)) {
    9.33          D3D_SetError("CreateTexture()", result);
    9.34          return -1;
    9.35 @@ -628,11 +616,6 @@
    9.36      D3DLOCKED_RECT locked;
    9.37      HRESULT result;
    9.38  
    9.39 -    if (texture->access != SDL_TEXTUREACCESS_LOCAL) {
    9.40 -        SDL_SetError("Can't lock remote video memory");
    9.41 -        return -1;
    9.42 -    }
    9.43 -
    9.44      d3drect.left = rect->x;
    9.45      d3drect.right = rect->x + rect->w;
    9.46      d3drect.top = rect->y;
    10.1 --- a/src/video/win32/SDL_gdirender.c	Sat Aug 11 20:46:24 2007 +0000
    10.2 +++ b/src/video/win32/SDL_gdirender.c	Sat Aug 11 20:54:31 2007 +0000
    10.3 @@ -304,7 +304,7 @@
    10.4      }
    10.5      data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format));
    10.6  
    10.7 -    if (data->yuv || texture->access == SDL_TEXTUREACCESS_LOCAL
    10.8 +    if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING
    10.9          || texture->format != display->current_mode.format) {
   10.10          int bmi_size;
   10.11          LPBITMAPINFO bmi;
    11.1 --- a/test/testsprite2.c	Sat Aug 11 20:46:24 2007 +0000
    11.2 +++ b/test/testsprite2.c	Sat Aug 11 20:54:31 2007 +0000
    11.3 @@ -63,8 +63,7 @@
    11.4      /* Create textures from the image */
    11.5      for (i = 0; i < state->num_windows; ++i) {
    11.6          SDL_SelectRenderer(state->windows[i]);
    11.7 -        sprites[i] =
    11.8 -            SDL_CreateTextureFromSurface(0, SDL_TEXTUREACCESS_REMOTE, temp);
    11.9 +        sprites[i] = SDL_CreateTextureFromSurface(0, temp);
   11.10          if (!sprites[i]) {
   11.11              fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
   11.12              SDL_FreeSurface(temp);