Emphasized the separation between SDL_Surface and SDL_Texture
authorSam Lantinga <slouken@libsdl.org>
Sat, 11 Aug 2007 20:54:31 +0000
changeset 2222 926294b2bb4e
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
--- a/include/SDL_compat.h	Sat Aug 11 20:46:24 2007 +0000
+++ b/include/SDL_compat.h	Sat Aug 11 20:54:31 2007 +0000
@@ -36,7 +36,7 @@
 /* *INDENT-ON* */
 #endif
 
-#define SDL_SWSURFACE       0x00000000
+#define SDL_SWSURFACE       0x00000000  /* Not used */
 #define SDL_ANYFORMAT       0x00100000
 #define SDL_HWPALETTE       0x00200000
 #define SDL_DOUBLEBUF       0x00400000
@@ -44,6 +44,7 @@
 #define SDL_RESIZABLE       0x01000000
 #define SDL_NOFRAME         0x02000000
 #define SDL_OPENGL          0x04000000
+#define SDL_HWSURFACE       0x08000001  /* Not used */
 #define SDL_ASYNCBLIT       0x08000000  /* Not used */
 #define SDL_HWACCEL         0x08000000  /* Not used */
 
--- a/include/SDL_video.h	Sat Aug 11 20:46:24 2007 +0000
+++ b/include/SDL_video.h	Sat Aug 11 20:54:31 2007 +0000
@@ -204,8 +204,8 @@
  */
 typedef enum
 {
-    SDL_TEXTUREACCESS_LOCAL,    /**< Lockable system memory */
-    SDL_TEXTUREACCESS_REMOTE    /**< Unlockable video memory */
+    SDL_TEXTUREACCESS_STATIC,    /**< Changes rarely, not lockable */
+    SDL_TEXTUREACCESS_STREAMING  /**< Changes frequently, lockable */
 } SDL_TextureAccess;
 
 /**
@@ -264,15 +264,14 @@
 
 /* These are the currently supported flags for the SDL_surface */
 /* Used internally (read-only) */
-#define SDL_HWSURFACE       0x00000001  /* Surface represents a texture */
-#define SDL_PREALLOC        0x00000002  /* Surface uses preallocated memory */
+#define SDL_PREALLOC        0x00000001  /* Surface uses preallocated memory */
 #define SDL_SRCALPHA        0x00000004  /* Blit uses source alpha blending */
 #define SDL_SRCCOLORKEY     0x00000008  /* Blit uses a source color key */
 #define SDL_RLEACCELOK      0x00000010  /* Private flag */
 #define SDL_RLEACCEL        0x00000020  /* Surface is RLE encoded */
 
 /* Evaluates to true if the surface needs to be locked before access */
-#define SDL_MUSTLOCK(S)	(((S)->flags & (SDL_HWSURFACE|SDL_RLEACCEL)) != 0)
+#define SDL_MUSTLOCK(S)	(((S)->flags & SDL_RLEACCEL) != 0)
 
 /* This structure should be treated as read-only, except for 'pixels',
    which, if not NULL, contains the raw pixel data for the surface.
@@ -288,9 +287,6 @@
     /* Application data associated with the surfade */
     void *userdata;             /* Read-write */
 
-    /* texture associated with the surface, if any */
-    SDL_TextureID textureID;    /* Read-only */
-
     /* information needed for surfaces requiring locks */
     int locked;                 /* Read-only */
     void *lock_data;            /* Read-only */
@@ -927,12 +923,11 @@
                                                         int h);
 
 /**
- * \fn SDL_TextureID SDL_CreateTextureFromSurface(Uint32 format, int access, SDL_Surface *surface)
+ * \fn SDL_TextureID SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface *surface)
  *
  * \brief Create a texture from an existing surface.
  *
  * \param format The format of the texture, or 0 to pick an appropriate format
- * \param access One of the enumerated values in SDL_TextureAccess
  * \param surface The surface containing pixel data used to fill the texture
  *
  * \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.
@@ -944,7 +939,6 @@
  */
 extern DECLSPEC SDL_TextureID SDLCALL SDL_CreateTextureFromSurface(Uint32
                                                                    format,
-                                                                   int access,
                                                                    SDL_Surface
                                                                    * surface);
 
@@ -970,7 +964,7 @@
  *
  * \brief Query the pixels of a texture, if the texture does not need to be locked for pixel access.
  *
- * \param texture A texture to be queried, which was created with SDL_TEXTUREACCESS_LOCAL
+ * \param texture A texture to be queried, which was created with SDL_TEXTUREACCESS_STREAMING
  * \param pixels A pointer filled with a pointer to the pixels for the texture 
  * \param pitch A pointer filled in with the pitch of the pixel data
  *
@@ -1155,7 +1149,7 @@
  *
  * \return 0 on success, or -1 if the texture is not valid
  *
- * \note This is a very slow function for textures not created with SDL_TEXTUREACCESS_LOCAL.
+ * \note This is a fairly slow function.
  */
 extern DECLSPEC int SDLCALL SDL_UpdateTexture(SDL_TextureID textureID,
                                               const SDL_Rect * rect,
@@ -1166,13 +1160,13 @@
  *
  * \brief Lock a portion of the texture for pixel access.
  *
- * \param texture The texture to lock for access, which must have been created with SDL_TEXTUREACCESS_LOCAL.
+ * \param textureID The texture to lock for access, which was created with SDL_TEXTUREACCESS_STREAMING.
  * \param rect A pointer to the rectangle to lock for access. If the rect is NULL, the entire texture will be locked.
  * \param markDirty If this is nonzero, the locked area will be marked dirty when the texture is unlocked.
  * \param pixels This is filled in with a pointer to the locked pixels, appropriately offset by the locked area.
  * \param pitch This is filled in with the pitch of the locked pixels.
  *
- * \return 0 on success, or -1 if the texture is not valid or was created with SDL_TEXTUREACCESS_REMOTe
+ * \return 0 on success, or -1 if the texture is not valid or was created with SDL_TEXTUREACCESS_STATIC
  *
  * \sa SDL_DirtyTexture()
  * \sa SDL_UnlockTexture()
@@ -1197,7 +1191,9 @@
  *
  * \brief Mark the specified rectangles of the texture as dirty.
  *
- * \note The texture must have been created with SDL_TEXTUREACCESS_LOCAL.
+ * \param textureID The texture to mark dirty, which was created with SDL_TEXTUREACCESS_STREAMING.
+ * \param numrects The number of rectangles pointed to by rects.
+ * \param rects The pointer to an array of dirty rectangles.
  *
  * \sa SDL_LockTexture()
  * \sa SDL_UnlockTexture()
@@ -1347,8 +1343,6 @@
                                                               Uint32 Gmask,
                                                               Uint32 Bmask,
                                                               Uint32 Amask);
-extern DECLSPEC SDL_Surface *SDLCALL
-SDL_CreateRGBSurfaceFromTexture(SDL_TextureID textureID);
 extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface * surface);
 
 /**
--- a/src/SDL_compat.c	Sat Aug 11 20:46:24 2007 +0000
+++ b/src/SDL_compat.c	Sat Aug 11 20:54:31 2007 +0000
@@ -328,6 +328,38 @@
     }
 }
 
+static SDL_Surface *
+CreateVideoSurface(SDL_TextureID textureID)
+{
+    SDL_Surface *surface;
+    Uint32 format;
+    int w, h;
+    int bpp;
+    Uint32 Rmask, Gmask, Bmask, Amask;
+    void *pixels;
+    int pitch;
+
+    if (SDL_QueryTexture(textureID, &format, NULL, &w, &h) < 0) {
+        return NULL;
+    }
+
+    if (!SDL_PixelFormatEnumToMasks
+        (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
+        SDL_SetError("Unknown texture format");
+        return NULL;
+    }
+
+    if (SDL_QueryTexturePixels(textureID, &pixels, &pitch) == 0) {
+        surface =
+            SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch, Rmask, Gmask,
+                                     Bmask, Amask);
+    } else {
+        surface =
+            SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
+    }
+    return surface;
+}
+
 SDL_Surface *
 SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
 {
@@ -483,23 +515,23 @@
          SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD) < 0) {
         return NULL;
     }
-    SDL_GetRenderDriverInfo(-1, &SDL_VideoRendererInfo);
+    SDL_GetRendererInfo(&SDL_VideoRendererInfo);
 
     /* Create a texture for the screen surface */
     SDL_VideoTexture =
-        SDL_CreateTexture(desired_format, SDL_TEXTUREACCESS_LOCAL, width,
+        SDL_CreateTexture(desired_format, SDL_TEXTUREACCESS_STREAMING, width,
                           height);
     if (!SDL_VideoTexture) {
         SDL_VideoTexture =
-            SDL_CreateTexture(SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_LOCAL,
-                              width, height);
+            SDL_CreateTexture(SDL_PIXELFORMAT_RGB888,
+                              SDL_TEXTUREACCESS_STREAMING, width, height);
     }
     if (!SDL_VideoTexture) {
         return NULL;
     }
 
     /* Create the screen surface */
-    SDL_VideoSurface = SDL_CreateRGBSurfaceFromTexture(SDL_VideoTexture);
+    SDL_VideoSurface = CreateVideoSurface(SDL_VideoTexture);
     if (!SDL_VideoSurface) {
         return NULL;
     }
@@ -518,23 +550,10 @@
     }
 
     /* Create a shadow surface if necessary */
-    if (((bpp != SDL_VideoSurface->format->BitsPerPixel)
-         && !(flags & SDL_ANYFORMAT))
-        || ((SDL_VideoSurface->flags & SDL_HWSURFACE)
-            && !(flags & SDL_HWSURFACE))) {
-        if ((bpp == SDL_VideoSurface->format->BitsPerPixel)
-            || (flags & SDL_ANYFORMAT)) {
-            SDL_ShadowSurface =
-                SDL_CreateRGBSurface(0, width, height,
-                                     SDL_VideoSurface->format->BitsPerPixel,
-                                     SDL_VideoSurface->format->Rmask,
-                                     SDL_VideoSurface->format->Gmask,
-                                     SDL_VideoSurface->format->Bmask,
-                                     SDL_VideoSurface->format->Amask);
-        } else {
-            SDL_ShadowSurface =
-                SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0);
-        }
+    if ((bpp != SDL_VideoSurface->format->BitsPerPixel)
+        && !(flags & SDL_ANYFORMAT)) {
+        SDL_ShadowSurface =
+            SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0);
         if (!SDL_ShadowSurface) {
             return NULL;
         }
@@ -638,8 +657,7 @@
         break;
     }
     format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
-    flags = SDL_PublicSurface->flags & SDL_HWSURFACE;
-    flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
+    flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
     converted = SDL_ConvertSurface(surface, format, flags);
     SDL_FreeFormat(format);
     return converted;
@@ -681,6 +699,22 @@
         screen = SDL_VideoSurface;
     }
     if (screen == SDL_VideoSurface) {
+        if (screen->flags & SDL_PREALLOC) {
+            /* The surface memory is maintained by the renderer */
+            SDL_DirtyTexture(SDL_VideoTexture, numrects, rects);
+        } else {
+            /* The surface memory needs to be copied to texture */
+            void *pixels;
+            int pitch = screen->pitch;
+            int psize = screen->format->BytesPerPixel;
+            for (i = 0; i < numrects; ++i) {
+                const SDL_Rect *rect = &rects[i];
+                void *pixels =
+                    (Uint8 *) screen->pixels + rect->y * pitch +
+                    rect->x * psize;
+                SDL_UpdateTexture(SDL_VideoTexture, rect, pixels, pitch);
+            }
+        }
         if (SDL_VideoRendererInfo.flags & SDL_RENDERER_PRESENTCOPY) {
             for (i = 0; i < numrects; ++i) {
                 SDL_RenderCopy(SDL_VideoTexture, &rects[i], &rects[i]);
@@ -1174,8 +1208,7 @@
     if (SDL_MUSTLOCK(screen)) {
         SDL_UnlockSurface(screen);
     }
-    if ((screen->flags & SDL_SCREEN_SURFACE) &&
-        !(screen->flags & SDL_HWSURFACE)) {
+    if (screen->flags & SDL_SCREEN_SURFACE) {
         SDL_VideoDevice *_this = SDL_GetVideoDevice();
         SDL_Window *window;
         SDL_Rect area;
@@ -1263,8 +1296,7 @@
     if (SDL_MUSTLOCK(screen)) {
         SDL_UnlockSurface(screen);
     }
-    if ((screen->flags & SDL_SCREEN_SURFACE) &&
-        !(screen->flags & SDL_HWSURFACE)) {
+    if (screen->flags & SDL_SCREEN_SURFACE) {
         SDL_VideoDevice *_this = SDL_GetVideoDevice();
         SDL_Window *window;
         SDL_Rect area;
@@ -1385,7 +1417,7 @@
     }
 
     overlay->hwdata->textureID =
-        SDL_CreateTexture(texture_format, SDL_TEXTUREACCESS_LOCAL, w, h);
+        SDL_CreateTexture(texture_format, SDL_TEXTUREACCESS_STREAMING, w, h);
     if (!overlay->hwdata->textureID) {
         SDL_FreeYUVOverlay(overlay);
         return NULL;
--- a/src/video/SDL_RLEaccel.c	Sat Aug 11 20:46:24 2007 +0000
+++ b/src/video/SDL_RLEaccel.c	Sat Aug 11 20:54:31 2007 +0000
@@ -1618,7 +1618,7 @@
 #undef ADD_TRANSL_COUNTS
 
     /* Now that we have it encoded, release the original pixels */
-    if (!(surface->flags & SDL_PREALLOC) && !(surface->flags & SDL_HWSURFACE)) {
+    if (!(surface->flags & SDL_PREALLOC)) {
         SDL_free(surface->pixels);
         surface->pixels = NULL;
     }
@@ -1783,7 +1783,7 @@
 #undef ADD_COUNTS
 
     /* Now that we have it encoded, release the original pixels */
-    if (!(surface->flags & SDL_PREALLOC) && !(surface->flags & SDL_HWSURFACE)) {
+    if (!(surface->flags & SDL_PREALLOC)) {
         SDL_free(surface->pixels);
         surface->pixels = NULL;
     }
@@ -1934,8 +1934,7 @@
     if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
         surface->flags &= ~SDL_RLEACCEL;
 
-        if (recode && !(surface->flags & SDL_PREALLOC)
-            && !(surface->flags & SDL_HWSURFACE)) {
+        if (recode && !(surface->flags & SDL_PREALLOC)) {
             if ((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
                 SDL_Rect full;
                 unsigned alpha_flag;
--- a/src/video/SDL_renderer_gl.c	Sat Aug 11 20:46:24 2007 +0000
+++ b/src/video/SDL_renderer_gl.c	Sat Aug 11 20:54:31 2007 +0000
@@ -38,6 +38,9 @@
 static int GL_ActivateRenderer(SDL_Renderer * renderer);
 static int GL_DisplayModeChanged(SDL_Renderer * renderer);
 static int GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static int GL_QueryTexturePixels(SDL_Renderer * renderer,
+                                 SDL_Texture * texture, void **pixels,
+                                 int *pitch);
 static int GL_SetTexturePalette(SDL_Renderer * renderer,
                                 SDL_Texture * texture,
                                 const SDL_Color * colors, int firstcolor,
@@ -245,6 +248,7 @@
     renderer->ActivateRenderer = GL_ActivateRenderer;
     renderer->DisplayModeChanged = GL_DisplayModeChanged;
     renderer->CreateTexture = GL_CreateTexture;
+    renderer->QueryTexturePixels = GL_QueryTexturePixels;
     renderer->SetTexturePalette = GL_SetTexturePalette;
     renderer->GetTexturePalette = GL_GetTexturePalette;
     renderer->SetTextureColorMod = GL_SetTextureColorMod;
@@ -492,6 +496,16 @@
         SDL_memset(data->palette, 0xFF, 3 * 256 * sizeof(Uint8));
     }
 
+    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
+        data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
+        data->pixels = SDL_malloc(texture->h * data->pitch);
+        if (!data->pixels) {
+            SDL_OutOfMemory();
+            SDL_free(data);
+            return -1;
+        }
+    }
+
     texture->driverdata = data;
 
     renderdata->glGetError();
@@ -523,6 +537,17 @@
 }
 
 static int
+GL_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
+                      void **pixels, int *pitch)
+{
+    GL_TextureData *data = (GL_TextureData *) texture->driverdata;
+
+    *pixels = data->pixels;
+    *pitch = data->pitch;
+    return 0;
+}
+
+static int
 GL_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
                      const SDL_Color * colors, int firstcolor, int ncolors)
 {
@@ -661,15 +686,6 @@
 {
     GL_TextureData *data = (GL_TextureData *) texture->driverdata;
 
-    if (!data->pixels) {
-        data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
-        data->pixels = SDL_malloc(texture->h * data->pitch);
-        if (!data->pixels) {
-            SDL_OutOfMemory();
-            return -1;
-        }
-    }
-
     if (markDirty) {
         SDL_AddDirtyRect(&data->dirty, rect);
     }
--- a/src/video/SDL_renderer_sw.c	Sat Aug 11 20:46:24 2007 +0000
+++ b/src/video/SDL_renderer_sw.c	Sat Aug 11 20:54:31 2007 +0000
@@ -125,7 +125,7 @@
     }
 
     texture->format = format;
-    texture->access = SDL_TEXTUREACCESS_LOCAL;
+    texture->access = SDL_TEXTUREACCESS_STREAMING;
     texture->w = w;
     texture->h = h;
     texture->renderer = renderer;
--- a/src/video/SDL_surface.c	Sat Aug 11 20:46:24 2007 +0000
+++ b/src/video/SDL_surface.c	Sat Aug 11 20:54:31 2007 +0000
@@ -170,62 +170,11 @@
     return surface;
 }
 
-SDL_Surface *
-SDL_CreateRGBSurfaceFromTexture(SDL_TextureID textureID)
-{
-    SDL_Surface *surface;
-    Uint32 format;
-    int w, h;
-    int bpp;
-    Uint32 Rmask, Gmask, Bmask, Amask;
-    void *pixels;
-    int pitch;
-
-    if (SDL_QueryTexture(textureID, &format, NULL, &w, &h) < 0) {
-        return NULL;
-    }
-
-    if (!SDL_PixelFormatEnumToMasks
-        (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
-        SDL_SetError("Unknown texture format");
-        return NULL;
-    }
-
-    if (SDL_QueryTexturePixels(textureID, &pixels, &pitch) == 0) {
-        surface =
-            SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch, Rmask, Gmask,
-                                     Bmask, Amask);
-    } else {
-        surface =
-            SDL_CreateRGBSurface(0, 0, 0, bpp, Rmask, Gmask, Bmask, Amask);
-        if (surface) {
-            surface->flags |= SDL_HWSURFACE;
-            surface->w = w;
-            surface->h = h;
-            surface->pitch = SDL_CalculatePitch(surface);
-            SDL_SetClipRect(surface, NULL);
-        }
-    }
-    if (surface) {
-        surface->textureID = textureID;
-    }
-
-    return surface;
-}
-
 static int
 SDL_SurfacePaletteChanged(void *userdata, SDL_Palette * palette)
 {
     SDL_Surface *surface = (SDL_Surface *) userdata;
 
-    if (surface->textureID) {
-        if (SDL_SetTexturePalette
-            (surface->textureID, palette->colors, 0, palette->ncolors) < 0) {
-            SDL_GetTexturePalette(surface->textureID, palette->colors, 0,
-                                  palette->ncolors);
-            return -1;
-        }
-    }
     SDL_FormatChanged(surface);
 
     return 0;
@@ -627,74 +576,9 @@
                 row += dst->pitch;
             }
         } else {
-#ifdef __powerpc__
-            /*
-             * SDL_memset() on PPC (both glibc and codewarrior) uses
-             * the dcbz (Data Cache Block Zero) instruction, which
-             * causes an alignment exception if the destination is
-             * uncachable, so only use it on software surfaces
-             */
-            if (dst->flags & SDL_HWSURFACE) {
-                if (dstrect->w >= 8) {
-                    /*
-                     * 64-bit stores are probably most
-                     * efficient to uncached video memory
-                     */
-                    double fill;
-                    SDL_memset(&fill, color, (sizeof fill));
-                    for (y = dstrect->h; y; y--) {
-                        Uint8 *d = row;
-                        unsigned n = x;
-                        unsigned nn;
-                        Uint8 c = color;
-                        double f = fill;
-                        while ((unsigned long) d & (sizeof(double) - 1)) {
-                            *d++ = c;
-                            n--;
-                        }
-                        nn = n / (sizeof(double) * 4);
-                        while (nn) {
-                            ((double *) d)[0] = f;
-                            ((double *) d)[1] = f;
-                            ((double *) d)[2] = f;
-                            ((double *) d)[3] = f;
-                            d += 4 * sizeof(double);
-                            nn--;
-                        }
-                        n &= ~(sizeof(double) * 4 - 1);
-                        nn = n / sizeof(double);
-                        while (nn) {
-                            *(double *) d = f;
-                            d += sizeof(double);
-                            nn--;
-                        }
-                        n &= ~(sizeof(double) - 1);
-                        while (n) {
-                            *d++ = c;
-                            n--;
-                        }
-                        row += dst->pitch;
-                    }
-                } else {
-                    /* narrow boxes */
-                    for (y = dstrect->h; y; y--) {
-                        Uint8 *d = row;
-                        Uint8 c = color;
-                        int n = x;
-                        while (n) {
-                            *d++ = c;
-                            n--;
-                        }
-                        row += dst->pitch;
-                    }
-                }
-            } else
-#endif /* __powerpc__ */
-            {
-                for (y = dstrect->h; y; y--) {
-                    SDL_memset(row, color, x);
-                    row += dst->pitch;
-                }
+            for (y = dstrect->h; y; y--) {
+                SDL_memset(row, color, x);
+                row += dst->pitch;
             }
         }
     } else {
@@ -753,13 +637,6 @@
 {
     if (!surface->locked) {
         /* Perform the lock */
-        if (surface->flags & SDL_HWSURFACE) {
-            if (SDL_LockTexture
-                (surface->textureID, NULL, 1, &surface->pixels,
-                 &surface->pitch) < 0) {
-                return (-1);
-            }
-        }
         if (surface->flags & SDL_RLEACCEL) {
             SDL_UnRLESurface(surface, 1);
             surface->flags |= SDL_RLEACCEL;     /* save accel'd state */
@@ -784,11 +661,6 @@
         return;
     }
 
-    /* Unlock hardware or accelerated surfaces */
-    if (surface->flags & SDL_HWSURFACE) {
-        SDL_UnlockTexture(surface->textureID);
-    }
-
     /* Update RLE encoded surface with new data */
     if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
         surface->flags &= ~SDL_RLEACCEL;        /* stop lying */
@@ -928,11 +800,6 @@
         SDL_FreeBlitMap(surface->map);
         surface->map = NULL;
     }
-    /* Should we destroy the texture too?
-       if (surface->textureID) {
-       SDL_DestroyTexture(surface->textureID);
-       }
-     */
     if (surface->pixels && ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC)) {
         SDL_free(surface->pixels);
     }
--- a/src/video/SDL_video.c	Sat Aug 11 20:46:24 2007 +0000
+++ b/src/video/SDL_video.c	Sat Aug 11 20:54:31 2007 +0000
@@ -1532,14 +1532,11 @@
 }
 
 SDL_TextureID
-SDL_CreateTextureFromSurface(Uint32 format, int access, SDL_Surface * surface)
+SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
 {
     SDL_TextureID textureID;
     Uint32 surface_flags = surface->flags;
     SDL_PixelFormat *fmt = surface->format;
-    Uint8 alpha;
-    SDL_Rect bounds;
-    SDL_Surface dst;
     int bpp;
     Uint32 Rmask, Gmask, Bmask, Amask;
 
@@ -1576,23 +1573,41 @@
         }
     }
 
-    textureID = SDL_CreateTexture(format, access, surface->w, surface->h);
+    textureID =
+        SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w,
+                          surface->h);
     if (!textureID) {
         return 0;
     }
 
-    /* Set up a destination surface for the texture update */
-    SDL_zero(dst);
-    dst.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
-    if (!dst.format) {
-        SDL_DestroyTexture(textureID);
-        return 0;
-    }
-    dst.w = surface->w;
-    dst.h = surface->h;
-    if (SDL_LockTexture(textureID, NULL, 1, &dst.pixels, &dst.pitch) == 0) {
-        dst.flags |= SDL_PREALLOC;
+    if (bpp == fmt->BitsPerPixel && Rmask == fmt->Rmask && Gmask == fmt->Gmask
+        && Bmask == fmt->Bmask && Amask == fmt->Amask) {
+        if (SDL_MUSTLOCK(surface)) {
+            if (SDL_LockSurface(surface) < 0) {
+                SDL_DestroyTexture(textureID);
+                return 0;
+            }
+            SDL_UpdateTexture(textureID, NULL, surface->pixels,
+                              surface->pitch);
+            SDL_UnlockSurface(surface);
+        } else {
+            SDL_UpdateTexture(textureID, NULL, surface->pixels,
+                              surface->pitch);
+        }
     } else {
+        Uint8 alpha;
+        SDL_Rect bounds;
+        SDL_Surface dst;
+
+        /* Set up a destination surface for the texture update */
+        SDL_zero(dst);
+        dst.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
+        if (!dst.format) {
+            SDL_DestroyTexture(textureID);
+            return 0;
+        }
+        dst.w = surface->w;
+        dst.h = surface->h;
         dst.pitch = SDL_CalculatePitch(&dst);
         dst.pixels = SDL_malloc(dst.h * dst.pitch);
         if (!dst.pixels) {
@@ -1601,76 +1616,72 @@
             SDL_OutOfMemory();
             return 0;
         }
-    }
 
-    /* Copy the palette if any */
-    if (SDL_ISPIXELFORMAT_INDEXED(format)) {
-        if (fmt->palette) {
-            SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
-                                  fmt->palette->ncolors);
-            SDL_SetSurfacePalette(&dst, fmt->palette);
-        } else {
-            dst.format->palette =
-                SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
-            if (!dst.format->palette) {
-                SDL_DestroyTexture(textureID);
-                SDL_FreeFormat(dst.format);
-                return 0;
+        /* Copy the palette if any */
+        if (SDL_ISPIXELFORMAT_INDEXED(format)) {
+            if (fmt->palette) {
+                SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
+                                      fmt->palette->ncolors);
+                SDL_SetSurfacePalette(&dst, fmt->palette);
+            } else {
+                dst.format->palette =
+                    SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
+                if (!dst.format->palette) {
+                    SDL_DestroyTexture(textureID);
+                    SDL_FreeFormat(dst.format);
+                    return 0;
+                }
+                SDL_DitherColors(dst.format->palette->colors,
+                                 SDL_BITSPERPIXEL(format));
             }
-            SDL_DitherColors(dst.format->palette->colors,
-                             SDL_BITSPERPIXEL(format));
         }
-    }
 
-    /* Make the texture transparent if the surface has colorkey */
-    if (surface_flags & SDL_SRCCOLORKEY) {
-        int row;
-        int length = dst.w * dst.format->BytesPerPixel;
-        Uint8 *p = (Uint8 *) dst.pixels;
-        for (row = 0; row < dst.h; ++row) {
-            SDL_memset(p, 0, length);
-            p += dst.pitch;
+        /* Make the texture transparent if the surface has colorkey */
+        if (surface_flags & SDL_SRCCOLORKEY) {
+            int row;
+            int length = dst.w * dst.format->BytesPerPixel;
+            Uint8 *p = (Uint8 *) dst.pixels;
+            for (row = 0; row < dst.h; ++row) {
+                SDL_memset(p, 0, length);
+                p += dst.pitch;
+            }
         }
-    }
 
-    /* Copy over the alpha channel */
-    if (surface_flags & SDL_SRCALPHA) {
-        if (fmt->Amask) {
-            surface->flags &= ~SDL_SRCALPHA;
-        } else {
-            /* FIXME: Need to make sure the texture has an alpha channel
-             *        and copy 'alpha' into the texture alpha channel.
-             */
-            alpha = surface->format->alpha;
-            SDL_SetAlpha(surface, 0, 0);
+        /* Copy over the alpha channel */
+        if (surface_flags & SDL_SRCALPHA) {
+            if (fmt->Amask) {
+                surface->flags &= ~SDL_SRCALPHA;
+            } else {
+                /* FIXME: Need to make sure the texture has an alpha channel
+                 *        and copy 'alpha' into the texture alpha channel.
+                 */
+                alpha = surface->format->alpha;
+                SDL_SetAlpha(surface, 0, 0);
+            }
         }
-    }
 
-    /* Copy over the image data */
-    bounds.x = 0;
-    bounds.y = 0;
-    bounds.w = surface->w;
-    bounds.h = surface->h;
-    SDL_LowerBlit(surface, &bounds, &dst, &bounds);
+        /* Copy over the image data */
+        bounds.x = 0;
+        bounds.y = 0;
+        bounds.w = surface->w;
+        bounds.h = surface->h;
+        SDL_LowerBlit(surface, &bounds, &dst, &bounds);
 
-    /* Clean up the original surface */
-    if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
-        Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
-        if (fmt->Amask) {
-            surface->flags |= SDL_SRCALPHA;
-        } else {
-            SDL_SetAlpha(surface, aflags, alpha);
+        /* Clean up the original surface */
+        if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
+            Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
+            if (fmt->Amask) {
+                surface->flags |= SDL_SRCALPHA;
+            } else {
+                SDL_SetAlpha(surface, aflags, alpha);
+            }
         }
-    }
 
-    /* Update the texture */
-    if (dst.flags & SDL_PREALLOC) {
-        SDL_UnlockTexture(textureID);
-    } else {
+        /* Update the texture */
         SDL_UpdateTexture(textureID, NULL, dst.pixels, dst.pitch);
         SDL_free(dst.pixels);
+        SDL_FreeFormat(dst.format);
     }
-    SDL_FreeFormat(dst.format);
 
     return textureID;
 }
@@ -1967,6 +1978,10 @@
     if (!texture) {
         return -1;
     }
+    if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
+        SDL_SetError("SDL_LockTexture(): texture must be streaming");
+        return -1;
+    }
 
     renderer = texture->renderer;
     if (!renderer->LockTexture) {
@@ -1994,6 +2009,9 @@
     if (!texture) {
         return;
     }
+    if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
+        return;
+    }
 
     renderer = texture->renderer;
     if (!renderer->UnlockTexture) {
@@ -2012,6 +2030,9 @@
     if (!texture) {
         return;
     }
+    if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
+        return;
+    }
 
     renderer = texture->renderer;
     if (!renderer->DirtyTexture) {
--- a/src/video/win32/SDL_d3drender.c	Sat Aug 11 20:46:24 2007 +0000
+++ b/src/video/win32/SDL_d3drender.c	Sat Aug 11 20:54:31 2007 +0000
@@ -459,7 +459,6 @@
     SDL_Window *window = SDL_GetWindowFromID(renderer->window);
     SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
     D3D_TextureData *data;
-    D3DPOOL pool;
     HRESULT result;
 
     data = (D3D_TextureData *) SDL_calloc(1, sizeof(*data));
@@ -470,22 +469,11 @@
 
     texture->driverdata = data;
 
-#if 1
-    /* FIXME: Do we want non-managed textures?
-       They need to be freed on device reset and then reloaded by the app...
-     */
-    texture->access = SDL_TEXTUREACCESS_LOCAL;
-#endif
-    if (texture->access == SDL_TEXTUREACCESS_LOCAL) {
-        pool = D3DPOOL_MANAGED;
-    } else {
-        pool = D3DPOOL_DEFAULT;
-    }
     result =
         IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
                                        texture->h, 1, 0,
                                        PixelFormatToD3DFMT(texture->format),
-                                       pool, &data->texture, NULL);
+                                       D3DPOOL_MANAGED, &data->texture, NULL);
     if (FAILED(result)) {
         D3D_SetError("CreateTexture()", result);
         return -1;
@@ -628,11 +616,6 @@
     D3DLOCKED_RECT locked;
     HRESULT result;
 
-    if (texture->access != SDL_TEXTUREACCESS_LOCAL) {
-        SDL_SetError("Can't lock remote video memory");
-        return -1;
-    }
-
     d3drect.left = rect->x;
     d3drect.right = rect->x + rect->w;
     d3drect.top = rect->y;
--- a/src/video/win32/SDL_gdirender.c	Sat Aug 11 20:46:24 2007 +0000
+++ b/src/video/win32/SDL_gdirender.c	Sat Aug 11 20:54:31 2007 +0000
@@ -304,7 +304,7 @@
     }
     data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format));
 
-    if (data->yuv || texture->access == SDL_TEXTUREACCESS_LOCAL
+    if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING
         || texture->format != display->current_mode.format) {
         int bmi_size;
         LPBITMAPINFO bmi;
--- a/test/testsprite2.c	Sat Aug 11 20:46:24 2007 +0000
+++ b/test/testsprite2.c	Sat Aug 11 20:54:31 2007 +0000
@@ -63,8 +63,7 @@
     /* Create textures from the image */
     for (i = 0; i < state->num_windows; ++i) {
         SDL_SelectRenderer(state->windows[i]);
-        sprites[i] =
-            SDL_CreateTextureFromSurface(0, SDL_TEXTUREACCESS_REMOTE, temp);
+        sprites[i] = SDL_CreateTextureFromSurface(0, temp);
         if (!sprites[i]) {
             fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
             SDL_FreeSurface(temp);