diff src/video/SDL_video.c @ 2222:926294b2bb4e

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.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 11 Aug 2007 20:54:31 +0000
parents 3ee59c43d784
children 989fb86ad1ec
line wrap: on
line diff
--- 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) {