Mercurial > sdl-ios-xcode
comparison src/render/software/SDL_renderer_sw.c @ 5169:4d39eeaad00b
Added a way to get a framebuffer interface for a window, and also a way to create a software renderer for an arbitrary surface.
The software renderer has been re-routed to use the framebuffer interface, which makes it possible to have software rendering available even on simple ports.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Thu, 03 Feb 2011 15:49:37 -0800 |
parents | d72793305335 |
children |
comparison
equal
deleted
inserted
replaced
5168:2b1989f59674 | 5169:4d39eeaad00b |
---|---|
67 | 67 |
68 SDL_RenderDriver SW_RenderDriver = { | 68 SDL_RenderDriver SW_RenderDriver = { |
69 SW_CreateRenderer, | 69 SW_CreateRenderer, |
70 { | 70 { |
71 "software", | 71 "software", |
72 (SDL_RENDERER_PRESENTVSYNC), | 72 0, |
73 8, | 73 8, |
74 { | 74 { |
75 SDL_PIXELFORMAT_RGB555, | 75 SDL_PIXELFORMAT_RGB555, |
76 SDL_PIXELFORMAT_RGB565, | 76 SDL_PIXELFORMAT_RGB565, |
77 SDL_PIXELFORMAT_RGB888, | 77 SDL_PIXELFORMAT_RGB888, |
85 0} | 85 0} |
86 }; | 86 }; |
87 | 87 |
88 typedef struct | 88 typedef struct |
89 { | 89 { |
90 Uint32 format; | |
91 SDL_bool updateSize; | 90 SDL_bool updateSize; |
92 SDL_Texture *texture; | 91 SDL_Surface *surface; |
93 SDL_Surface surface; | |
94 SDL_Renderer *renderer; | |
95 } SW_RenderData; | 92 } SW_RenderData; |
96 | 93 |
97 static SDL_Texture * | |
98 CreateTexture(SDL_Renderer * renderer, Uint32 format, int w, int h) | |
99 { | |
100 SDL_Texture *texture; | |
101 | |
102 texture = (SDL_Texture *) SDL_calloc(1, sizeof(*texture)); | |
103 if (!texture) { | |
104 SDL_OutOfMemory(); | |
105 return NULL; | |
106 } | |
107 | |
108 texture->format = format; | |
109 texture->access = SDL_TEXTUREACCESS_STREAMING; | |
110 texture->w = w; | |
111 texture->h = h; | |
112 texture->renderer = renderer; | |
113 | |
114 if (renderer->CreateTexture(renderer, texture) < 0) { | |
115 SDL_free(texture); | |
116 return NULL; | |
117 } | |
118 return texture; | |
119 } | |
120 | |
121 static void | |
122 DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) | |
123 { | |
124 renderer->DestroyTexture(renderer, texture); | |
125 SDL_free(texture); | |
126 } | |
127 | 94 |
128 SDL_Renderer * | 95 SDL_Renderer * |
129 SW_CreateRenderer(SDL_Window * window, Uint32 flags) | 96 SW_CreateRendererForSurface(SDL_Surface * surface) |
130 { | 97 { |
131 SDL_Renderer *renderer; | 98 SDL_Renderer *renderer; |
132 SW_RenderData *data; | 99 SW_RenderData *data; |
133 int i; | 100 |
134 int w, h; | 101 if (!surface) { |
135 Uint32 format; | 102 SDL_SetError("Can't create renderer for NULL surface"); |
136 int bpp; | |
137 Uint32 Rmask, Gmask, Bmask, Amask; | |
138 Uint32 renderer_flags; | |
139 const char *desired_driver; | |
140 | |
141 format = SDL_GetWindowPixelFormat(window); | |
142 if (!SDL_PixelFormatEnumToMasks | |
143 (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { | |
144 SDL_SetError("Unknown display format"); | |
145 return NULL; | 103 return NULL; |
146 } | 104 } |
147 | 105 |
148 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); | 106 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); |
149 if (!renderer) { | 107 if (!renderer) { |
155 if (!data) { | 113 if (!data) { |
156 SW_DestroyRenderer(renderer); | 114 SW_DestroyRenderer(renderer); |
157 SDL_OutOfMemory(); | 115 SDL_OutOfMemory(); |
158 return NULL; | 116 return NULL; |
159 } | 117 } |
118 data->surface = surface; | |
119 | |
160 renderer->WindowEvent = SW_WindowEvent; | 120 renderer->WindowEvent = SW_WindowEvent; |
161 renderer->CreateTexture = SW_CreateTexture; | 121 renderer->CreateTexture = SW_CreateTexture; |
162 renderer->SetTextureColorMod = SW_SetTextureColorMod; | 122 renderer->SetTextureColorMod = SW_SetTextureColorMod; |
163 renderer->SetTextureAlphaMod = SW_SetTextureAlphaMod; | 123 renderer->SetTextureAlphaMod = SW_SetTextureAlphaMod; |
164 renderer->SetTextureBlendMode = SW_SetTextureBlendMode; | 124 renderer->SetTextureBlendMode = SW_SetTextureBlendMode; |
172 renderer->RenderCopy = SW_RenderCopy; | 132 renderer->RenderCopy = SW_RenderCopy; |
173 renderer->RenderReadPixels = SW_RenderReadPixels; | 133 renderer->RenderReadPixels = SW_RenderReadPixels; |
174 renderer->RenderPresent = SW_RenderPresent; | 134 renderer->RenderPresent = SW_RenderPresent; |
175 renderer->DestroyRenderer = SW_DestroyRenderer; | 135 renderer->DestroyRenderer = SW_DestroyRenderer; |
176 renderer->info = SW_RenderDriver.info; | 136 renderer->info = SW_RenderDriver.info; |
177 renderer->info.flags = 0; | |
178 renderer->window = window; | |
179 renderer->driverdata = data; | 137 renderer->driverdata = data; |
180 | 138 |
181 data->format = format; | 139 return renderer; |
182 | 140 } |
183 /* Find a render driver that we can use to display data */ | 141 |
184 renderer_flags = 0; | 142 SDL_Renderer * |
185 if (flags & SDL_RENDERER_PRESENTVSYNC) { | 143 SW_CreateRenderer(SDL_Window * window, Uint32 flags) |
186 renderer_flags |= SDL_RENDERER_PRESENTVSYNC; | 144 { |
187 } | 145 SDL_Surface *surface; |
188 desired_driver = SDL_getenv("SDL_VIDEO_RENDERER_SWDRIVER"); | 146 |
189 for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { | 147 surface = SDL_GetWindowSurface(window); |
190 SDL_RendererInfo info; | 148 if (!surface) { |
191 SDL_GetRenderDriverInfo(i, &info); | |
192 if (SDL_strcmp(info.name, SW_RenderDriver.info.name) == 0) { | |
193 continue; | |
194 } | |
195 if (desired_driver | |
196 && SDL_strcasecmp(desired_driver, info.name) != 0) { | |
197 continue; | |
198 } | |
199 data->renderer = SDL_CreateRenderer(window, i, renderer_flags); | |
200 if (data->renderer) { | |
201 break; | |
202 } | |
203 } | |
204 if (i == SDL_GetNumRenderDrivers()) { | |
205 SW_DestroyRenderer(renderer); | |
206 SDL_SetError("Couldn't find display render driver"); | |
207 return NULL; | 149 return NULL; |
208 } | 150 } |
209 if (data->renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) { | 151 return SW_CreateRendererForSurface(surface); |
210 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; | 152 } |
211 } | 153 |
212 | 154 static SDL_Surface * |
213 /* Create the textures we'll use for display */ | |
214 SDL_GetWindowSize(window, &w, &h); | |
215 data->texture = CreateTexture(data->renderer, data->format, w, h); | |
216 if (!data->texture) { | |
217 SW_DestroyRenderer(renderer); | |
218 return NULL; | |
219 } | |
220 | |
221 /* Create a surface we'll use for rendering */ | |
222 data->surface.flags = SDL_PREALLOC; | |
223 data->surface.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); | |
224 if (!data->surface.format) { | |
225 SW_DestroyRenderer(renderer); | |
226 return NULL; | |
227 } | |
228 | |
229 return renderer; | |
230 } | |
231 | |
232 static SDL_Texture * | |
233 SW_ActivateRenderer(SDL_Renderer * renderer) | 155 SW_ActivateRenderer(SDL_Renderer * renderer) |
234 { | 156 { |
235 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; | 157 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; |
236 SDL_Window *window = renderer->window; | 158 SDL_Window *window = renderer->window; |
237 | 159 |
238 if (data->updateSize) { | 160 if (data->updateSize) { |
239 /* Recreate the textures for the new window size */ | 161 data->surface = SDL_GetWindowSurface(window); |
240 int w, h; | 162 data->updateSize = SDL_FALSE; |
241 if (data->texture) { | 163 } |
242 DestroyTexture(data->renderer, data->texture); | 164 return data->surface; |
243 } | |
244 SDL_GetWindowSize(window, &w, &h); | |
245 data->texture = CreateTexture(data->renderer, data->format, w, h); | |
246 if (data->texture) { | |
247 data->updateSize = SDL_FALSE; | |
248 } | |
249 } | |
250 return data->texture; | |
251 } | 165 } |
252 | 166 |
253 static void | 167 static void |
254 SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) | 168 SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) |
255 { | 169 { |
354 | 268 |
355 static int | 269 static int |
356 SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, | 270 SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, |
357 int count) | 271 int count) |
358 { | 272 { |
359 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; | 273 SDL_Surface *surface = SW_ActivateRenderer(renderer); |
360 SDL_Texture *texture = SW_ActivateRenderer(renderer); | 274 |
361 SDL_Rect rect; | 275 if (!surface) { |
362 int i; | 276 return -1; |
363 int x, y; | 277 } |
364 int status = 0; | |
365 | |
366 if (!texture) { | |
367 return -1; | |
368 } | |
369 | |
370 /* Get the smallest rectangle that contains everything */ | |
371 rect.x = 0; | |
372 rect.y = 0; | |
373 rect.w = texture->w; | |
374 rect.h = texture->h; | |
375 if (!SDL_EnclosePoints(points, count, &rect, &rect)) { | |
376 /* Nothing to draw */ | |
377 return 0; | |
378 } | |
379 | |
380 if (data->renderer->LockTexture(data->renderer, texture, &rect, | |
381 &data->surface.pixels, | |
382 &data->surface.pitch) < 0) { | |
383 return -1; | |
384 } | |
385 | |
386 data->surface.clip_rect.w = data->surface.w = rect.w; | |
387 data->surface.clip_rect.h = data->surface.h = rect.h; | |
388 | 278 |
389 /* Draw the points! */ | 279 /* Draw the points! */ |
390 if (renderer->blendMode == SDL_BLENDMODE_NONE) { | 280 if (renderer->blendMode == SDL_BLENDMODE_NONE) { |
391 Uint32 color = SDL_MapRGBA(data->surface.format, | 281 Uint32 color = SDL_MapRGBA(surface->format, |
392 renderer->r, renderer->g, renderer->b, | 282 renderer->r, renderer->g, renderer->b, |
393 renderer->a); | 283 renderer->a); |
394 | 284 |
395 for (i = 0; i < count; ++i) { | 285 return SDL_DrawPoints(surface, points, count, color); |
396 x = points[i].x - rect.x; | |
397 y = points[i].y - rect.y; | |
398 | |
399 status = SDL_DrawPoint(&data->surface, x, y, color); | |
400 } | |
401 } else { | 286 } else { |
402 for (i = 0; i < count; ++i) { | 287 return SDL_BlendPoints(surface, points, count, |
403 x = points[i].x - rect.x; | 288 renderer->blendMode, |
404 y = points[i].y - rect.y; | 289 renderer->r, renderer->g, renderer->b, |
405 | 290 renderer->a); |
406 status = SDL_BlendPoint(&data->surface, x, y, | 291 } |
407 renderer->blendMode, | |
408 renderer->r, renderer->g, renderer->b, | |
409 renderer->a); | |
410 } | |
411 } | |
412 | |
413 data->renderer->UnlockTexture(data->renderer, texture); | |
414 | |
415 return status; | |
416 } | 292 } |
417 | 293 |
418 static int | 294 static int |
419 SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, | 295 SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, |
420 int count) | 296 int count) |
421 { | 297 { |
422 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; | 298 SDL_Surface *surface = SW_ActivateRenderer(renderer); |
423 SDL_Texture *texture = SW_ActivateRenderer(renderer); | 299 |
424 SDL_Rect clip, rect; | 300 if (!surface) { |
425 int i; | 301 return -1; |
426 int x1, y1, x2, y2; | 302 } |
427 int status = 0; | 303 |
428 | 304 /* Draw the lines! */ |
429 if (!texture) { | |
430 return -1; | |
431 } | |
432 | |
433 /* Get the smallest rectangle that contains everything */ | |
434 clip.x = 0; | |
435 clip.y = 0; | |
436 clip.w = texture->w; | |
437 clip.h = texture->h; | |
438 SDL_EnclosePoints(points, count, NULL, &rect); | |
439 if (!SDL_IntersectRect(&rect, &clip, &rect)) { | |
440 /* Nothing to draw */ | |
441 return 0; | |
442 } | |
443 | |
444 if (data->renderer->LockTexture(data->renderer, texture, &rect, | |
445 &data->surface.pixels, | |
446 &data->surface.pitch) < 0) { | |
447 return -1; | |
448 } | |
449 | |
450 data->surface.clip_rect.w = data->surface.w = rect.w; | |
451 data->surface.clip_rect.h = data->surface.h = rect.h; | |
452 | |
453 /* Draw the points! */ | |
454 if (renderer->blendMode == SDL_BLENDMODE_NONE) { | 305 if (renderer->blendMode == SDL_BLENDMODE_NONE) { |
455 Uint32 color = SDL_MapRGBA(data->surface.format, | 306 Uint32 color = SDL_MapRGBA(surface->format, |
456 renderer->r, renderer->g, renderer->b, | 307 renderer->r, renderer->g, renderer->b, |
457 renderer->a); | 308 renderer->a); |
458 | 309 |
459 for (i = 1; i < count; ++i) { | 310 return SDL_DrawLines(surface, points, count, color); |
460 x1 = points[i-1].x - rect.x; | |
461 y1 = points[i-1].y - rect.y; | |
462 x2 = points[i].x - rect.x; | |
463 y2 = points[i].y - rect.y; | |
464 | |
465 status = SDL_DrawLine(&data->surface, x1, y1, x2, y2, color); | |
466 } | |
467 } else { | 311 } else { |
468 for (i = 1; i < count; ++i) { | 312 return SDL_BlendLines(surface, points, count, |
469 x1 = points[i-1].x - rect.x; | 313 renderer->blendMode, |
470 y1 = points[i-1].y - rect.y; | 314 renderer->r, renderer->g, renderer->b, |
471 x2 = points[i].x - rect.x; | 315 renderer->a); |
472 y2 = points[i].y - rect.y; | 316 } |
473 | 317 } |
474 status = SDL_BlendLine(&data->surface, x1, y1, x2, y2, | 318 |
475 renderer->blendMode, | 319 static int |
320 SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, | |
321 int count) | |
322 { | |
323 SDL_Surface *surface = SW_ActivateRenderer(renderer); | |
324 | |
325 if (!surface) { | |
326 return -1; | |
327 } | |
328 | |
329 if (renderer->blendMode == SDL_BLENDMODE_NONE) { | |
330 Uint32 color = SDL_MapRGBA(surface->format, | |
476 renderer->r, renderer->g, renderer->b, | 331 renderer->r, renderer->g, renderer->b, |
477 renderer->a); | 332 renderer->a); |
478 } | 333 return SDL_FillRects(surface, rects, count, color); |
479 } | 334 } else { |
480 | 335 return SDL_BlendFillRects(surface, rects, count, |
481 data->renderer->UnlockTexture(data->renderer, texture); | 336 renderer->blendMode, |
482 | 337 renderer->r, renderer->g, renderer->b, |
483 return status; | 338 renderer->a); |
484 } | 339 } |
485 | |
486 static int | |
487 SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, | |
488 int count) | |
489 { | |
490 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; | |
491 SDL_Texture *texture = SW_ActivateRenderer(renderer); | |
492 SDL_Rect clip, rect; | |
493 Uint32 color = 0; | |
494 int i; | |
495 int status = 0; | |
496 | |
497 if (!texture) { | |
498 return -1; | |
499 } | |
500 | |
501 clip.x = 0; | |
502 clip.y = 0; | |
503 clip.w = texture->w; | |
504 clip.h = texture->h; | |
505 | |
506 if (renderer->blendMode == SDL_BLENDMODE_NONE) { | |
507 color = SDL_MapRGBA(data->surface.format, | |
508 renderer->r, renderer->g, renderer->b, | |
509 renderer->a); | |
510 } | |
511 | |
512 for (i = 0; i < count; ++i) { | |
513 if (!SDL_IntersectRect(rects[i], &clip, &rect)) { | |
514 /* Nothing to draw */ | |
515 continue; | |
516 } | |
517 | |
518 if (data->renderer->LockTexture(data->renderer, texture, &rect, | |
519 &data->surface.pixels, | |
520 &data->surface.pitch) < 0) { | |
521 return -1; | |
522 } | |
523 | |
524 data->surface.clip_rect.w = data->surface.w = rect.w; | |
525 data->surface.clip_rect.h = data->surface.h = rect.h; | |
526 | |
527 if (renderer->blendMode == SDL_BLENDMODE_NONE) { | |
528 status = SDL_FillRect(&data->surface, NULL, color); | |
529 } else { | |
530 status = SDL_BlendFillRect(&data->surface, NULL, | |
531 renderer->blendMode, | |
532 renderer->r, renderer->g, renderer->b, | |
533 renderer->a); | |
534 } | |
535 | |
536 data->renderer->UnlockTexture(data->renderer, texture); | |
537 } | |
538 return status; | |
539 } | 340 } |
540 | 341 |
541 static int | 342 static int |
542 SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, | 343 SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, |
543 const SDL_Rect * srcrect, const SDL_Rect * dstrect) | 344 const SDL_Rect * srcrect, const SDL_Rect * dstrect) |
544 { | 345 { |
545 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; | 346 SDL_Surface *surface = SW_ActivateRenderer(renderer); |
546 SDL_Surface *surface; | 347 SDL_Surface *src = (SDL_Surface *) texture->driverdata; |
547 SDL_Rect real_srcrect; | 348 SDL_Rect final_rect = *dstrect; |
548 SDL_Rect real_dstrect; | 349 |
549 int status; | 350 if (!surface) { |
550 | 351 return -1; |
551 if (!SW_ActivateRenderer(renderer)) { | 352 } |
552 return -1; | 353 return SDL_BlitSurface(src, srcrect, surface, &final_rect); |
553 } | |
554 | |
555 if (data->renderer->LockTexture(data->renderer, data->texture, dstrect, | |
556 &data->surface.pixels, | |
557 &data->surface.pitch) < 0) { | |
558 return -1; | |
559 } | |
560 | |
561 surface = (SDL_Surface *) texture->driverdata; | |
562 real_srcrect = *srcrect; | |
563 | |
564 data->surface.w = dstrect->w; | |
565 data->surface.h = dstrect->h; | |
566 data->surface.clip_rect.w = dstrect->w; | |
567 data->surface.clip_rect.h = dstrect->h; | |
568 real_dstrect = data->surface.clip_rect; | |
569 | |
570 status = SDL_LowerBlit(surface, &real_srcrect, &data->surface, &real_dstrect); | |
571 data->renderer->UnlockTexture(data->renderer, data->texture); | |
572 return status; | |
573 } | 354 } |
574 | 355 |
575 static int | 356 static int |
576 SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, | 357 SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, |
577 Uint32 format, void * pixels, int pitch) | 358 Uint32 format, void * pixels, int pitch) |
578 { | 359 { |
579 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; | 360 SDL_Surface *surface = SW_ActivateRenderer(renderer); |
580 | 361 Uint32 src_format; |
581 if (!SW_ActivateRenderer(renderer)) { | 362 void *src_pixels; |
582 return -1; | 363 |
583 } | 364 if (!surface) { |
584 | 365 return -1; |
585 if (data->renderer->LockTexture(data->renderer, data->texture, rect, | 366 } |
586 &data->surface.pixels, | 367 |
587 &data->surface.pitch) < 0) { | 368 if (rect->x < 0 || rect->x+rect->w > surface->w || |
588 return -1; | 369 rect->y < 0 || rect->y+rect->h > surface->h) { |
589 } | 370 SDL_SetError("Tried to read outside of surface bounds"); |
590 | 371 return -1; |
591 SDL_ConvertPixels(rect->w, rect->h, | 372 } |
592 data->format, data->surface.pixels, data->surface.pitch, | 373 |
593 format, pixels, pitch); | 374 src_format = SDL_MasksToPixelFormatEnum( |
594 | 375 surface->format->BitsPerPixel, |
595 data->renderer->UnlockTexture(data->renderer, data->texture); | 376 surface->format->Rmask, surface->format->Gmask, |
596 return 0; | 377 surface->format->Bmask, surface->format->Amask); |
378 | |
379 src_pixels = (void*)((Uint8 *) surface->pixels + | |
380 rect->y * surface->pitch + | |
381 rect->x * surface->format->BytesPerPixel); | |
382 | |
383 return SDL_ConvertPixels(rect->w, rect->h, | |
384 src_format, src_pixels, surface->pitch, | |
385 format, pixels, pitch); | |
597 } | 386 } |
598 | 387 |
599 static void | 388 static void |
600 SW_RenderPresent(SDL_Renderer * renderer) | 389 SW_RenderPresent(SDL_Renderer * renderer) |
601 { | 390 { |
602 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; | 391 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; |
603 SDL_Texture *texture = SW_ActivateRenderer(renderer); | 392 SDL_Window *window = renderer->window; |
604 SDL_Rect rect; | 393 |
605 | 394 if (window) { |
606 if (!texture) { | 395 SDL_UpdateWindowSurface(window); |
607 return; | 396 } |
608 } | |
609 | |
610 /* Send the data to the display */ | |
611 rect.x = 0; | |
612 rect.y = 0; | |
613 rect.w = texture->w; | |
614 rect.h = texture->h; | |
615 data->renderer->RenderCopy(data->renderer, texture, &rect, &rect); | |
616 data->renderer->RenderPresent(data->renderer); | |
617 } | 397 } |
618 | 398 |
619 static void | 399 static void |
620 SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) | 400 SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) |
621 { | 401 { |
626 | 406 |
627 static void | 407 static void |
628 SW_DestroyRenderer(SDL_Renderer * renderer) | 408 SW_DestroyRenderer(SDL_Renderer * renderer) |
629 { | 409 { |
630 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; | 410 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; |
631 SDL_Window *window = renderer->window; | |
632 | 411 |
633 if (data) { | 412 if (data) { |
634 if (data->texture) { | |
635 DestroyTexture(data->renderer, data->texture); | |
636 } | |
637 if (data->surface.format) { | |
638 SDL_FreeFormat(data->surface.format); | |
639 } | |
640 if (data->renderer) { | |
641 data->renderer->DestroyRenderer(data->renderer); | |
642 } | |
643 SDL_free(data); | 413 SDL_free(data); |
644 } | 414 } |
645 SDL_free(renderer); | 415 SDL_free(renderer); |
646 } | 416 } |
647 | 417 |