src/render/software/SDL_render_sw.c
changeset 5297 1800dc39b74c
parent 5296 48067bfc300c
child 5298 7b1cac2c2230
     1.1 --- a/src/render/software/SDL_render_sw.c	Mon Feb 14 11:50:18 2011 -0600
     1.2 +++ b/src/render/software/SDL_render_sw.c	Tue Feb 15 13:59:59 2011 -0800
     1.3 @@ -51,13 +51,14 @@
     1.4  static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
     1.5                            const SDL_Rect * rect, void **pixels, int *pitch);
     1.6  static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
     1.7 -static void SW_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect);
     1.8 +static int SW_UpdateViewport(SDL_Renderer * renderer);
     1.9 +static int SW_RenderClear(SDL_Renderer * renderer);
    1.10  static int SW_RenderDrawPoints(SDL_Renderer * renderer,
    1.11                                 const SDL_Point * points, int count);
    1.12  static int SW_RenderDrawLines(SDL_Renderer * renderer,
    1.13                                const SDL_Point * points, int count);
    1.14  static int SW_RenderFillRects(SDL_Renderer * renderer,
    1.15 -                              const SDL_Rect ** rects, int count);
    1.16 +                              const SDL_Rect * rects, int count);
    1.17  static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
    1.18                           const SDL_Rect * srcrect, const SDL_Rect * dstrect);
    1.19  static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    1.20 @@ -89,11 +90,23 @@
    1.21  
    1.22  typedef struct
    1.23  {
    1.24 -    SDL_bool updateSize;
    1.25      SDL_Surface *surface;
    1.26  } SW_RenderData;
    1.27  
    1.28  
    1.29 +static SDL_Surface *
    1.30 +SW_ActivateRenderer(SDL_Renderer * renderer)
    1.31 +{
    1.32 +    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
    1.33 +
    1.34 +    if (!data->surface) {
    1.35 +        data->surface = SDL_GetWindowSurface(renderer->window);
    1.36 +
    1.37 +        SW_UpdateViewport(renderer);
    1.38 +    }
    1.39 +    return data->surface;
    1.40 +}
    1.41 +
    1.42  SDL_Renderer *
    1.43  SW_CreateRendererForSurface(SDL_Surface * surface)
    1.44  {
    1.45 @@ -127,8 +140,9 @@
    1.46      renderer->UpdateTexture = SW_UpdateTexture;
    1.47      renderer->LockTexture = SW_LockTexture;
    1.48      renderer->UnlockTexture = SW_UnlockTexture;
    1.49 -    renderer->SetClipRect = SW_SetClipRect;
    1.50 +    renderer->UpdateViewport = SW_UpdateViewport;
    1.51      renderer->DestroyTexture = SW_DestroyTexture;
    1.52 +    renderer->RenderClear = SW_RenderClear;
    1.53      renderer->RenderDrawPoints = SW_RenderDrawPoints;
    1.54      renderer->RenderDrawLines = SW_RenderDrawLines;
    1.55      renderer->RenderFillRects = SW_RenderFillRects;
    1.56 @@ -139,6 +153,8 @@
    1.57      renderer->info = SW_RenderDriver.info;
    1.58      renderer->driverdata = data;
    1.59  
    1.60 +    SW_ActivateRenderer(renderer);
    1.61 +
    1.62      return renderer;
    1.63  }
    1.64  
    1.65 @@ -154,26 +170,13 @@
    1.66      return SW_CreateRendererForSurface(surface);
    1.67  }
    1.68  
    1.69 -static SDL_Surface *
    1.70 -SW_ActivateRenderer(SDL_Renderer * renderer)
    1.71 -{
    1.72 -    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
    1.73 -    SDL_Window *window = renderer->window;
    1.74 -
    1.75 -    if (data->updateSize) {
    1.76 -        data->surface = SDL_GetWindowSurface(window);
    1.77 -        data->updateSize = SDL_FALSE;
    1.78 -    }
    1.79 -    return data->surface;
    1.80 -}
    1.81 -
    1.82  static void
    1.83  SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
    1.84  {
    1.85      SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
    1.86  
    1.87      if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
    1.88 -        data->updateSize = SDL_TRUE;
    1.89 +        data->surface = NULL;
    1.90      }
    1.91  }
    1.92  
    1.93 @@ -269,15 +272,46 @@
    1.94  {
    1.95  }
    1.96  
    1.97 -static void
    1.98 -SW_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
    1.99 +static int
   1.100 +SW_UpdateViewport(SDL_Renderer * renderer)
   1.101 +{
   1.102 +    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
   1.103 +    SDL_Surface *surface = data->surface;
   1.104 +
   1.105 +    if (!surface) {
   1.106 +        /* We'll update the viewport after we recreate the surface */
   1.107 +        return 0;
   1.108 +    }
   1.109 +
   1.110 +    if (!renderer->viewport.w && !renderer->viewport.h) {
   1.111 +        /* There may be no window, so update the viewport directly */
   1.112 +        renderer->viewport.w = surface->w;
   1.113 +        renderer->viewport.h = surface->h;
   1.114 +    }
   1.115 +    //SDL_SetClipRect(data->surface, &renderer->viewport);
   1.116 +    return 0;
   1.117 +}
   1.118 +
   1.119 +static int
   1.120 +SW_RenderClear(SDL_Renderer * renderer)
   1.121  {
   1.122      SDL_Surface *surface = SW_ActivateRenderer(renderer);
   1.123 +    Uint32 color;
   1.124 +    SDL_Rect clip_rect;
   1.125  
   1.126      if (!surface) {
   1.127 -        return;
   1.128 +        return -1;
   1.129      }
   1.130 -    SDL_SetClipRect(surface, rect);
   1.131 +
   1.132 +    color = SDL_MapRGBA(surface->format,
   1.133 +                        renderer->r, renderer->g, renderer->b, renderer->a);
   1.134 +
   1.135 +    /* By definition the clear ignores the clip rect */
   1.136 +    clip_rect = surface->clip_rect;
   1.137 +    SDL_SetClipRect(surface, NULL);
   1.138 +    SDL_FillRect(surface, NULL, color);
   1.139 +    SDL_SetClipRect(surface, &clip_rect);
   1.140 +    return 0;
   1.141  }
   1.142  
   1.143  static int
   1.144 @@ -285,24 +319,44 @@
   1.145                      int count)
   1.146  {
   1.147      SDL_Surface *surface = SW_ActivateRenderer(renderer);
   1.148 +    SDL_Point *temp = NULL;
   1.149 +    int status;
   1.150  
   1.151      if (!surface) {
   1.152          return -1;
   1.153      }
   1.154  
   1.155 +    if (renderer->viewport.x || renderer->viewport.y) {
   1.156 +        int i;
   1.157 +        int x = renderer->viewport.x;
   1.158 +        int y = renderer->viewport.y;
   1.159 +
   1.160 +        temp = SDL_stack_alloc(SDL_Point, count);
   1.161 +        for (i = 0; i < count; ++i) {
   1.162 +            temp[i].x = x + points[i].x;
   1.163 +            temp[i].y = y + points[i].x;
   1.164 +        }
   1.165 +        points = temp;
   1.166 +    }
   1.167 +
   1.168      /* Draw the points! */
   1.169      if (renderer->blendMode == SDL_BLENDMODE_NONE) {
   1.170          Uint32 color = SDL_MapRGBA(surface->format,
   1.171                                     renderer->r, renderer->g, renderer->b,
   1.172                                     renderer->a);
   1.173  
   1.174 -        return SDL_DrawPoints(surface, points, count, color);
   1.175 +        status = SDL_DrawPoints(surface, points, count, color);
   1.176      } else {
   1.177 -        return SDL_BlendPoints(surface, points, count,
   1.178 -                               renderer->blendMode,
   1.179 -                               renderer->r, renderer->g, renderer->b,
   1.180 -                               renderer->a);
   1.181 +        status = SDL_BlendPoints(surface, points, count,
   1.182 +                                renderer->blendMode,
   1.183 +                                renderer->r, renderer->g, renderer->b,
   1.184 +                                renderer->a);
   1.185      }
   1.186 +
   1.187 +    if (temp) {
   1.188 +        SDL_stack_free(temp);
   1.189 +    }
   1.190 +    return status;
   1.191  }
   1.192  
   1.193  static int
   1.194 @@ -310,47 +364,88 @@
   1.195                     int count)
   1.196  {
   1.197      SDL_Surface *surface = SW_ActivateRenderer(renderer);
   1.198 +    SDL_Point *temp = NULL;
   1.199 +    int status;
   1.200  
   1.201      if (!surface) {
   1.202          return -1;
   1.203      }
   1.204  
   1.205 +    if (renderer->viewport.x || renderer->viewport.y) {
   1.206 +        int i;
   1.207 +        int x = renderer->viewport.x;
   1.208 +        int y = renderer->viewport.y;
   1.209 +
   1.210 +        temp = SDL_stack_alloc(SDL_Point, count);
   1.211 +        for (i = 0; i < count; ++i) {
   1.212 +            temp[i].x = x + points[i].x;
   1.213 +            temp[i].y = y + points[i].y;
   1.214 +        }
   1.215 +        points = temp;
   1.216 +    }
   1.217 +
   1.218      /* Draw the lines! */
   1.219      if (renderer->blendMode == SDL_BLENDMODE_NONE) {
   1.220          Uint32 color = SDL_MapRGBA(surface->format,
   1.221                                     renderer->r, renderer->g, renderer->b,
   1.222                                     renderer->a);
   1.223  
   1.224 -        return SDL_DrawLines(surface, points, count, color);
   1.225 +        status = SDL_DrawLines(surface, points, count, color);
   1.226      } else {
   1.227 -        return SDL_BlendLines(surface, points, count,
   1.228 -                              renderer->blendMode,
   1.229 -                              renderer->r, renderer->g, renderer->b,
   1.230 -                              renderer->a);
   1.231 +        status = SDL_BlendLines(surface, points, count,
   1.232 +                                renderer->blendMode,
   1.233 +                                renderer->r, renderer->g, renderer->b,
   1.234 +                                renderer->a);
   1.235      }
   1.236 +
   1.237 +    if (temp) {
   1.238 +        SDL_stack_free(temp);
   1.239 +    }
   1.240 +    return status;
   1.241  }
   1.242  
   1.243  static int
   1.244 -SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
   1.245 -                   int count)
   1.246 +SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count)
   1.247  {
   1.248      SDL_Surface *surface = SW_ActivateRenderer(renderer);
   1.249 +    SDL_Rect *temp = NULL;
   1.250 +    int status;
   1.251  
   1.252      if (!surface) {
   1.253          return -1;
   1.254      }
   1.255  
   1.256 +    if (renderer->viewport.x || renderer->viewport.y) {
   1.257 +        int i;
   1.258 +        int x = renderer->viewport.x;
   1.259 +        int y = renderer->viewport.y;
   1.260 +
   1.261 +        temp = SDL_stack_alloc(SDL_Rect, count);
   1.262 +        for (i = 0; i < count; ++i) {
   1.263 +            temp[i].x = x + rects[i].x;
   1.264 +            temp[i].y = y + rects[i].y;
   1.265 +            temp[i].w = rects[i].w;
   1.266 +            temp[i].h = rects[i].h;
   1.267 +        }
   1.268 +        rects = temp;
   1.269 +    }
   1.270 +
   1.271      if (renderer->blendMode == SDL_BLENDMODE_NONE) {
   1.272          Uint32 color = SDL_MapRGBA(surface->format,
   1.273                                     renderer->r, renderer->g, renderer->b,
   1.274                                     renderer->a);
   1.275 -        return SDL_FillRects(surface, rects, count, color);
   1.276 +        status = SDL_FillRects(surface, rects, count, color);
   1.277      } else {
   1.278 -        return SDL_BlendFillRects(surface, rects, count,
   1.279 -                                     renderer->blendMode,
   1.280 -                                     renderer->r, renderer->g, renderer->b,
   1.281 -                                     renderer->a);
   1.282 +        status = SDL_BlendFillRects(surface, rects, count,
   1.283 +                                    renderer->blendMode,
   1.284 +                                    renderer->r, renderer->g, renderer->b,
   1.285 +                                    renderer->a);
   1.286      }
   1.287 +
   1.288 +    if (temp) {
   1.289 +        SDL_stack_free(temp);
   1.290 +    }
   1.291 +    return status;
   1.292  }
   1.293  
   1.294  static int
   1.295 @@ -365,6 +460,10 @@
   1.296          return -1;
   1.297      }
   1.298  
   1.299 +    if (renderer->viewport.x || renderer->viewport.y) {
   1.300 +        final_rect.x += renderer->viewport.x;
   1.301 +        final_rect.y += renderer->viewport.y;
   1.302 +    }
   1.303      if ( srcrect->w == final_rect.w && srcrect->h == final_rect.h ) {
   1.304          return SDL_BlitSurface(src, srcrect, surface, &final_rect);
   1.305      } else {
   1.306 @@ -379,22 +478,27 @@
   1.307      SDL_Surface *surface = SW_ActivateRenderer(renderer);
   1.308      Uint32 src_format;
   1.309      void *src_pixels;
   1.310 +    SDL_Rect final_rect;
   1.311  
   1.312      if (!surface) {
   1.313          return -1;
   1.314      }
   1.315  
   1.316 +    if (renderer->viewport.x || renderer->viewport.y) {
   1.317 +        final_rect.x = renderer->viewport.x + rect->x;
   1.318 +        final_rect.y = renderer->viewport.y + rect->y;
   1.319 +        final_rect.w = rect->w;
   1.320 +        final_rect.h = rect->h;
   1.321 +        rect = &final_rect;
   1.322 +    }
   1.323 +
   1.324      if (rect->x < 0 || rect->x+rect->w > surface->w ||
   1.325          rect->y < 0 || rect->y+rect->h > surface->h) {
   1.326          SDL_SetError("Tried to read outside of surface bounds");
   1.327          return -1;
   1.328      }
   1.329  
   1.330 -    src_format = SDL_MasksToPixelFormatEnum(
   1.331 -                    surface->format->BitsPerPixel,
   1.332 -                    surface->format->Rmask, surface->format->Gmask,
   1.333 -                    surface->format->Bmask, surface->format->Amask);
   1.334 -
   1.335 +    src_format = surface->format->format;
   1.336      src_pixels = (void*)((Uint8 *) surface->pixels +
   1.337                      rect->y * surface->pitch +
   1.338                      rect->x * surface->format->BytesPerPixel);