Don't free the surface since the application might be still using it.
authorSam Lantinga <slouken@libsdl.org>
Fri, 04 Feb 2011 12:24:28 -0800
changeset 517251b4cfdf7ebb
parent 5171 34e2d5115786
child 5173 ebfedf3787b1
Don't free the surface since the application might be still using it.
Also experimented with texture rectangle updates, but I think at this point the full rect update gives the most consistent results.
src/video/SDL_video.c
     1.1 --- a/src/video/SDL_video.c	Fri Feb 04 12:22:52 2011 -0800
     1.2 +++ b/src/video/SDL_video.c	Fri Feb 04 12:24:28 2011 -0800
     1.3 @@ -104,6 +104,7 @@
     1.4      SDL_Texture *texture;
     1.5      void *pixels;
     1.6      int pitch;
     1.7 +    int bytes_per_pixel;
     1.8  } SDL_WindowTextureData;
     1.9  
    1.10  static int
    1.11 @@ -176,7 +177,8 @@
    1.12      }
    1.13  
    1.14      /* Create framebuffer data */
    1.15 -    data->pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
    1.16 +    data->bytes_per_pixel = SDL_BYTESPERPIXEL(*format);
    1.17 +    data->pitch = (((window->w * data->bytes_per_pixel) + 3) & ~3);
    1.18      data->pixels = SDL_malloc(window->h * data->pitch);
    1.19      if (!data->pixels) {
    1.20          SDL_OutOfMemory();
    1.21 @@ -192,6 +194,12 @@
    1.22  SDL_UpdateWindowTexture(_THIS, SDL_Window * window, int numrects, SDL_Rect * rects)
    1.23  {
    1.24      SDL_WindowTextureData *data;
    1.25 +#ifdef UPDATE_TEXTURE_SUBRECTS
    1.26 +    void *src, *dst;
    1.27 +    int src_pitch;
    1.28 +    int dst_pitch;
    1.29 +    int i, row, length;
    1.30 +#endif
    1.31  
    1.32      data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
    1.33      if (!data || !data->texture) {
    1.34 @@ -199,12 +207,33 @@
    1.35          return -1;
    1.36      }
    1.37  
    1.38 +#ifdef UPDATE_TEXTURE_SUBRECTS
    1.39 +    src_pitch = data->pitch;
    1.40 +    for (i = 0; i < numrects; ++i) {
    1.41 +        src = (void *)((Uint8 *)data->pixels +
    1.42 +                        rects[i].y * src_pitch +
    1.43 +                        rects[i].x * data->bytes_per_pixel);
    1.44 +        if (SDL_LockTexture(data->texture, &rects[i], &dst, &dst_pitch) < 0) {
    1.45 +            return -1;
    1.46 +        }
    1.47 +        length = rects[i].w * data->bytes_per_pixel;
    1.48 +        for (row = rects[i].h; row--; ) {
    1.49 +            SDL_memcpy(dst, src, length);
    1.50 +            src = (Uint8*)src + src_pitch;
    1.51 +            dst = (Uint8*)dst + dst_pitch;
    1.52 +        }
    1.53 +        SDL_UnlockTexture(data->texture);
    1.54 +    }
    1.55 +#else
    1.56      if (SDL_UpdateTexture(data->texture, NULL, data->pixels, data->pitch) < 0) {
    1.57          return -1;
    1.58      }
    1.59 +#endif
    1.60 +
    1.61      if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) {
    1.62          return -1;
    1.63      }
    1.64 +
    1.65      SDL_RenderPresent(data->renderer);
    1.66      return 0;
    1.67  }
    1.68 @@ -1389,9 +1418,14 @@
    1.69  {
    1.70      CHECK_WINDOW_MAGIC(window, NULL);
    1.71  
    1.72 -    if (!window->surface) {
    1.73 +    if (!window->surface_valid) {
    1.74 +        if (window->surface) {
    1.75 +            window->surface->refcount = 0;
    1.76 +            SDL_FreeSurface(window->surface);
    1.77 +        }
    1.78          window->surface = SDL_CreateWindowFramebuffer(window);
    1.79          if (window->surface) {
    1.80 +            window->surface_valid = SDL_TRUE;
    1.81              window->surface->refcount = 0x7FFFFFF;
    1.82          }
    1.83      }
    1.84 @@ -1418,7 +1452,7 @@
    1.85  {
    1.86      CHECK_WINDOW_MAGIC(window, -1);
    1.87  
    1.88 -    if (!window->surface) {
    1.89 +    if (!window->surface_valid) {
    1.90          SDL_SetError("Window surface is invalid, please call SDL_GetWindowSurface() to get a new surface");
    1.91          return -1;
    1.92      }
    1.93 @@ -1474,11 +1508,7 @@
    1.94  void
    1.95  SDL_OnWindowResized(SDL_Window * window)
    1.96  {
    1.97 -    if (window->surface) {
    1.98 -        window->surface->refcount = 0;
    1.99 -        SDL_FreeSurface(window->surface);
   1.100 -        window->surface = NULL;
   1.101 -    }
   1.102 +    window->surface_valid = SDL_FALSE;
   1.103  }
   1.104  
   1.105  void