comparison src/render/software/SDL_renderer_sw.c @ 5157:fb424691cfc7

Moved the rendering code out to a separate directory in the hope that it can someday be completely decoupled from the rest of the library and be expanded to an awesome 2D on 3D library.
author Sam Lantinga <slouken@libsdl.org>
date Wed, 02 Feb 2011 14:34:54 -0800
parents src/video/SDL_renderer_sw.c@be02be2ea897
children 307ccc9c135e
comparison
equal deleted inserted replaced
5156:3e4086b3bcd2 5157:fb424691cfc7
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2010 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 #include "../SDL_sysrender.h"
25 #include "../../video/SDL_pixels_c.h"
26 #include "../../video/SDL_yuv_sw_c.h"
27
28
29 /* SDL surface based renderer implementation */
30
31 static SDL_Renderer *SW_CreateRenderer(SDL_Window * window, Uint32 flags);
32 static void SW_WindowEvent(SDL_Renderer * renderer,
33 const SDL_WindowEvent *event);
34 static int SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
35 static int SW_QueryTexturePixels(SDL_Renderer * renderer,
36 SDL_Texture * texture, void **pixels,
37 int *pitch);
38 static int SW_SetTextureColorMod(SDL_Renderer * renderer,
39 SDL_Texture * texture);
40 static int SW_SetTextureAlphaMod(SDL_Renderer * renderer,
41 SDL_Texture * texture);
42 static int SW_SetTextureBlendMode(SDL_Renderer * renderer,
43 SDL_Texture * texture);
44 static int SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
45 const SDL_Rect * rect, const void *pixels,
46 int pitch);
47 static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
48 const SDL_Rect * rect, int markDirty, void **pixels,
49 int *pitch);
50 static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
51 static int SW_RenderDrawPoints(SDL_Renderer * renderer,
52 const SDL_Point * points, int count);
53 static int SW_RenderDrawLines(SDL_Renderer * renderer,
54 const SDL_Point * points, int count);
55 static int SW_RenderFillRects(SDL_Renderer * renderer,
56 const SDL_Rect ** rects, int count);
57 static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
58 const SDL_Rect * srcrect, const SDL_Rect * dstrect);
59 static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
60 Uint32 format, void * pixels, int pitch);
61 static int SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
62 Uint32 format, const void * pixels, int pitch);
63 static void SW_RenderPresent(SDL_Renderer * renderer);
64 static void SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
65 static void SW_DestroyRenderer(SDL_Renderer * renderer);
66
67
68 SDL_RenderDriver SW_RenderDriver = {
69 SW_CreateRenderer,
70 {
71 "software",
72 (SDL_RENDERER_PRESENTVSYNC),
73 13,
74 {
75 SDL_PIXELFORMAT_RGB555,
76 SDL_PIXELFORMAT_RGB565,
77 SDL_PIXELFORMAT_RGB888,
78 SDL_PIXELFORMAT_BGR888,
79 SDL_PIXELFORMAT_ARGB8888,
80 SDL_PIXELFORMAT_RGBA8888,
81 SDL_PIXELFORMAT_ABGR8888,
82 SDL_PIXELFORMAT_BGRA8888,
83 SDL_PIXELFORMAT_YV12,
84 SDL_PIXELFORMAT_IYUV,
85 SDL_PIXELFORMAT_YUY2,
86 SDL_PIXELFORMAT_UYVY,
87 SDL_PIXELFORMAT_YVYU},
88 0,
89 0}
90 };
91
92 typedef struct
93 {
94 Uint32 format;
95 SDL_bool updateSize;
96 SDL_Texture *texture;
97 SDL_Surface surface;
98 SDL_Renderer *renderer;
99 SDL_DirtyRectList dirty;
100 } SW_RenderData;
101
102 static SDL_Texture *
103 CreateTexture(SDL_Renderer * renderer, Uint32 format, int w, int h)
104 {
105 SDL_Texture *texture;
106
107 texture = (SDL_Texture *) SDL_calloc(1, sizeof(*texture));
108 if (!texture) {
109 SDL_OutOfMemory();
110 return NULL;
111 }
112
113 texture->format = format;
114 texture->access = SDL_TEXTUREACCESS_STREAMING;
115 texture->w = w;
116 texture->h = h;
117 texture->renderer = renderer;
118
119 if (renderer->CreateTexture(renderer, texture) < 0) {
120 SDL_free(texture);
121 return NULL;
122 }
123 return texture;
124 }
125
126 static void
127 DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
128 {
129 renderer->DestroyTexture(renderer, texture);
130 SDL_free(texture);
131 }
132
133 SDL_Renderer *
134 SW_CreateRenderer(SDL_Window * window, Uint32 flags)
135 {
136 SDL_Renderer *renderer;
137 SW_RenderData *data;
138 int i;
139 Uint32 format;
140 int bpp;
141 Uint32 Rmask, Gmask, Bmask, Amask;
142 Uint32 renderer_flags;
143 const char *desired_driver;
144
145 format = SDL_GetWindowPixelFormat(window);
146 if (!SDL_PixelFormatEnumToMasks
147 (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
148 SDL_SetError("Unknown display format");
149 return NULL;
150 }
151
152 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
153 if (!renderer) {
154 SDL_OutOfMemory();
155 return NULL;
156 }
157
158 data = (SW_RenderData *) SDL_calloc(1, sizeof(*data));
159 if (!data) {
160 SW_DestroyRenderer(renderer);
161 SDL_OutOfMemory();
162 return NULL;
163 }
164 renderer->WindowEvent = SW_WindowEvent;
165 renderer->CreateTexture = SW_CreateTexture;
166 renderer->QueryTexturePixels = SW_QueryTexturePixels;
167 renderer->SetTextureColorMod = SW_SetTextureColorMod;
168 renderer->SetTextureAlphaMod = SW_SetTextureAlphaMod;
169 renderer->SetTextureBlendMode = SW_SetTextureBlendMode;
170 renderer->UpdateTexture = SW_UpdateTexture;
171 renderer->LockTexture = SW_LockTexture;
172 renderer->UnlockTexture = SW_UnlockTexture;
173 renderer->DestroyTexture = SW_DestroyTexture;
174 renderer->RenderDrawPoints = SW_RenderDrawPoints;
175 renderer->RenderDrawLines = SW_RenderDrawLines;
176 renderer->RenderFillRects = SW_RenderFillRects;
177 renderer->RenderCopy = SW_RenderCopy;
178 renderer->RenderReadPixels = SW_RenderReadPixels;
179 renderer->RenderWritePixels = SW_RenderWritePixels;
180 renderer->RenderPresent = SW_RenderPresent;
181 renderer->DestroyRenderer = SW_DestroyRenderer;
182 renderer->info = SW_RenderDriver.info;
183 renderer->info.flags = 0;
184 renderer->window = window;
185 renderer->driverdata = data;
186
187 data->format = format;
188
189 /* Find a render driver that we can use to display data */
190 renderer_flags = 0;
191 if (flags & SDL_RENDERER_PRESENTVSYNC) {
192 renderer_flags |= SDL_RENDERER_PRESENTVSYNC;
193 }
194 desired_driver = SDL_getenv("SDL_VIDEO_RENDERER_SWDRIVER");
195 for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
196 SDL_RendererInfo info;
197 SDL_GetRenderDriverInfo(i, &info);
198 if (SDL_strcmp(info.name, SW_RenderDriver.info.name) == 0) {
199 continue;
200 }
201 if (desired_driver
202 && SDL_strcasecmp(desired_driver, info.name) != 0) {
203 continue;
204 }
205 data->renderer = SDL_CreateRenderer(window, i, renderer_flags);
206 if (data->renderer) {
207 break;
208 }
209 }
210 if (i == SDL_GetNumRenderDrivers()) {
211 SW_DestroyRenderer(renderer);
212 SDL_SetError("Couldn't find display render driver");
213 return NULL;
214 }
215 if (data->renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
216 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
217 }
218
219 /* Create the textures we'll use for display */
220 data->texture =
221 CreateTexture(data->renderer, data->format, window->w, window->h);
222 if (!data->texture) {
223 SW_DestroyRenderer(renderer);
224 return NULL;
225 }
226
227 /* Create a surface we'll use for rendering */
228 data->surface.flags = SDL_PREALLOC;
229 data->surface.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
230 if (!data->surface.format) {
231 SW_DestroyRenderer(renderer);
232 return NULL;
233 }
234
235 return renderer;
236 }
237
238 static SDL_Texture *
239 SW_ActivateRenderer(SDL_Renderer * renderer)
240 {
241 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
242 SDL_Window *window = renderer->window;
243
244 if (data->updateSize) {
245 /* Recreate the textures for the new window size */
246 if (data->texture) {
247 DestroyTexture(data->renderer, data->texture);
248 }
249 data->texture = CreateTexture(data->renderer, data->format,
250 window->w, window->h);
251 if (data->texture) {
252 data->updateSize = SDL_FALSE;
253 }
254 }
255 return data->texture;
256 }
257
258 static void
259 SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
260 {
261 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
262
263 if (event->event == SDL_WINDOWEVENT_RESIZED) {
264 data->updateSize = SDL_TRUE;
265 }
266 }
267
268 static int
269 SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
270 {
271 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
272 texture->driverdata =
273 SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h);
274 } else {
275 int bpp;
276 Uint32 Rmask, Gmask, Bmask, Amask;
277
278 if (!SDL_PixelFormatEnumToMasks
279 (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
280 SDL_SetError("Unknown texture format");
281 return -1;
282 }
283
284 texture->driverdata =
285 SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask,
286 Bmask, Amask);
287 SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g,
288 texture->b);
289 SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a);
290 SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode);
291
292 if (texture->access == SDL_TEXTUREACCESS_STATIC) {
293 SDL_SetSurfaceRLE(texture->driverdata, 1);
294 }
295 }
296
297 if (!texture->driverdata) {
298 return -1;
299 }
300 return 0;
301 }
302
303 static int
304 SW_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
305 void **pixels, int *pitch)
306 {
307 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
308 return SDL_SW_QueryYUVTexturePixels((SDL_SW_YUVTexture *)
309 texture->driverdata, pixels,
310 pitch);
311 } else {
312 SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
313
314 *pixels = surface->pixels;
315 *pitch = surface->pitch;
316 return 0;
317 }
318 }
319
320 static int
321 SW_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
322 {
323 SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
324 return SDL_SetSurfaceColorMod(surface, texture->r, texture->g,
325 texture->b);
326 }
327
328 static int
329 SW_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
330 {
331 SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
332 return SDL_SetSurfaceAlphaMod(surface, texture->a);
333 }
334
335 static int
336 SW_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
337 {
338 SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
339 return SDL_SetSurfaceBlendMode(surface, texture->blendMode);
340 }
341
342 static int
343 SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
344 const SDL_Rect * rect, const void *pixels, int pitch)
345 {
346 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
347 return SDL_SW_UpdateYUVTexture((SDL_SW_YUVTexture *)
348 texture->driverdata, rect, pixels,
349 pitch);
350 } else {
351 SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
352 Uint8 *src, *dst;
353 int row;
354 size_t length;
355
356 src = (Uint8 *) pixels;
357 dst =
358 (Uint8 *) surface->pixels + rect->y * surface->pitch +
359 rect->x * surface->format->BytesPerPixel;
360 length = rect->w * surface->format->BytesPerPixel;
361 for (row = 0; row < rect->h; ++row) {
362 SDL_memcpy(dst, src, length);
363 src += pitch;
364 dst += surface->pitch;
365 }
366 return 0;
367 }
368 }
369
370 static int
371 SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
372 const SDL_Rect * rect, int markDirty, void **pixels,
373 int *pitch)
374 {
375 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
376 return SDL_SW_LockYUVTexture((SDL_SW_YUVTexture *)
377 texture->driverdata, rect, markDirty,
378 pixels, pitch);
379 } else {
380 SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
381
382 *pixels =
383 (void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch +
384 rect->x * surface->format->BytesPerPixel);
385 *pitch = surface->pitch;
386 return 0;
387 }
388 }
389
390 static void
391 SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
392 {
393 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
394 SDL_SW_UnlockYUVTexture((SDL_SW_YUVTexture *) texture->driverdata);
395 }
396 }
397
398 static int
399 SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
400 int count)
401 {
402 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
403 SDL_Texture *texture = SW_ActivateRenderer(renderer);
404 SDL_Rect rect;
405 int i;
406 int x, y;
407 int status = 0;
408
409 if (!texture) {
410 return -1;
411 }
412
413 /* Get the smallest rectangle that contains everything */
414 rect.x = 0;
415 rect.y = 0;
416 rect.w = texture->w;
417 rect.h = texture->h;
418 if (!SDL_EnclosePoints(points, count, &rect, &rect)) {
419 /* Nothing to draw */
420 return 0;
421 }
422
423 if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
424 &data->surface.pixels,
425 &data->surface.pitch) < 0) {
426 return -1;
427 }
428
429 data->surface.clip_rect.w = data->surface.w = rect.w;
430 data->surface.clip_rect.h = data->surface.h = rect.h;
431
432 /* Draw the points! */
433 if (renderer->blendMode == SDL_BLENDMODE_NONE) {
434 Uint32 color = SDL_MapRGBA(data->surface.format,
435 renderer->r, renderer->g, renderer->b,
436 renderer->a);
437
438 for (i = 0; i < count; ++i) {
439 x = points[i].x - rect.x;
440 y = points[i].y - rect.y;
441
442 status = SDL_DrawPoint(&data->surface, x, y, color);
443 }
444 } else {
445 for (i = 0; i < count; ++i) {
446 x = points[i].x - rect.x;
447 y = points[i].y - rect.y;
448
449 status = SDL_BlendPoint(&data->surface, x, y,
450 renderer->blendMode,
451 renderer->r, renderer->g, renderer->b,
452 renderer->a);
453 }
454 }
455
456 data->renderer->UnlockTexture(data->renderer, texture);
457
458 return status;
459 }
460
461 static int
462 SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
463 int count)
464 {
465 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
466 SDL_Texture *texture = SW_ActivateRenderer(renderer);
467 SDL_Rect clip, rect;
468 int i;
469 int x1, y1, x2, y2;
470 int status = 0;
471
472 if (!texture) {
473 return -1;
474 }
475
476 /* Get the smallest rectangle that contains everything */
477 clip.x = 0;
478 clip.y = 0;
479 clip.w = texture->w;
480 clip.h = texture->h;
481 SDL_EnclosePoints(points, count, NULL, &rect);
482 if (!SDL_IntersectRect(&rect, &clip, &rect)) {
483 /* Nothing to draw */
484 return 0;
485 }
486
487 if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
488 &data->surface.pixels,
489 &data->surface.pitch) < 0) {
490 return -1;
491 }
492
493 data->surface.clip_rect.w = data->surface.w = rect.w;
494 data->surface.clip_rect.h = data->surface.h = rect.h;
495
496 /* Draw the points! */
497 if (renderer->blendMode == SDL_BLENDMODE_NONE) {
498 Uint32 color = SDL_MapRGBA(data->surface.format,
499 renderer->r, renderer->g, renderer->b,
500 renderer->a);
501
502 for (i = 1; i < count; ++i) {
503 x1 = points[i-1].x - rect.x;
504 y1 = points[i-1].y - rect.y;
505 x2 = points[i].x - rect.x;
506 y2 = points[i].y - rect.y;
507
508 status = SDL_DrawLine(&data->surface, x1, y1, x2, y2, color);
509 }
510 } else {
511 for (i = 1; i < count; ++i) {
512 x1 = points[i-1].x - rect.x;
513 y1 = points[i-1].y - rect.y;
514 x2 = points[i].x - rect.x;
515 y2 = points[i].y - rect.y;
516
517 status = SDL_BlendLine(&data->surface, x1, y1, x2, y2,
518 renderer->blendMode,
519 renderer->r, renderer->g, renderer->b,
520 renderer->a);
521 }
522 }
523
524 data->renderer->UnlockTexture(data->renderer, texture);
525
526 return status;
527 }
528
529 static int
530 SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
531 int count)
532 {
533 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
534 SDL_Texture *texture = SW_ActivateRenderer(renderer);
535 SDL_Rect clip, rect;
536 Uint32 color = 0;
537 int i;
538 int status = 0;
539
540 if (!texture) {
541 return -1;
542 }
543
544 clip.x = 0;
545 clip.y = 0;
546 clip.w = texture->w;
547 clip.h = texture->h;
548
549 if (renderer->blendMode == SDL_BLENDMODE_NONE) {
550 color = SDL_MapRGBA(data->surface.format,
551 renderer->r, renderer->g, renderer->b,
552 renderer->a);
553 }
554
555 for (i = 0; i < count; ++i) {
556 if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
557 /* Nothing to draw */
558 continue;
559 }
560
561 if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
562 &data->surface.pixels,
563 &data->surface.pitch) < 0) {
564 return -1;
565 }
566
567 data->surface.clip_rect.w = data->surface.w = rect.w;
568 data->surface.clip_rect.h = data->surface.h = rect.h;
569
570 if (renderer->blendMode == SDL_BLENDMODE_NONE) {
571 status = SDL_FillRect(&data->surface, NULL, color);
572 } else {
573 status = SDL_BlendFillRect(&data->surface, NULL,
574 renderer->blendMode,
575 renderer->r, renderer->g, renderer->b,
576 renderer->a);
577 }
578
579 data->renderer->UnlockTexture(data->renderer, texture);
580 }
581 return status;
582 }
583
584 static int
585 SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
586 const SDL_Rect * srcrect, const SDL_Rect * dstrect)
587 {
588 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
589 int status;
590
591 if (!SW_ActivateRenderer(renderer)) {
592 return -1;
593 }
594
595 if (data->renderer->LockTexture(data->renderer, data->texture,
596 dstrect, 1, &data->surface.pixels,
597 &data->surface.pitch) < 0) {
598 return -1;
599 }
600
601 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
602 status =
603 SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata,
604 srcrect, data->format, dstrect->w, dstrect->h,
605 data->surface.pixels, data->surface.pitch);
606 } else {
607 SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
608 SDL_Rect real_srcrect = *srcrect;
609 SDL_Rect real_dstrect;
610
611 data->surface.w = dstrect->w;
612 data->surface.h = dstrect->h;
613 data->surface.clip_rect.w = dstrect->w;
614 data->surface.clip_rect.h = dstrect->h;
615 real_dstrect = data->surface.clip_rect;
616
617 status =
618 SDL_LowerBlit(surface, &real_srcrect, &data->surface,
619 &real_dstrect);
620 }
621 data->renderer->UnlockTexture(data->renderer, data->texture);
622 return status;
623 }
624
625 static int
626 SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
627 Uint32 format, void * pixels, int pitch)
628 {
629 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
630
631 if (!SW_ActivateRenderer(renderer)) {
632 return -1;
633 }
634
635 if (data->renderer->LockTexture(data->renderer, data->texture,
636 rect, 0, &data->surface.pixels,
637 &data->surface.pitch) < 0) {
638 return -1;
639 }
640
641 SDL_ConvertPixels(rect->w, rect->h,
642 data->format, data->surface.pixels, data->surface.pitch,
643 format, pixels, pitch);
644
645 data->renderer->UnlockTexture(data->renderer, data->texture);
646 return 0;
647 }
648
649 static int
650 SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
651 Uint32 format, const void * pixels, int pitch)
652 {
653 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
654
655 if (!SW_ActivateRenderer(renderer)) {
656 return -1;
657 }
658
659 if (data->renderer->LockTexture(data->renderer, data->texture,
660 rect, 1, &data->surface.pixels,
661 &data->surface.pitch) < 0) {
662 return -1;
663 }
664
665 SDL_ConvertPixels(rect->w, rect->h, format, pixels, pitch,
666 data->format, data->surface.pixels, data->surface.pitch);
667
668 data->renderer->UnlockTexture(data->renderer, data->texture);
669 return 0;
670 }
671
672 static void
673 SW_RenderPresent(SDL_Renderer * renderer)
674 {
675 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
676 SDL_Texture *texture = SW_ActivateRenderer(renderer);
677 SDL_Rect rect;
678
679 if (!texture) {
680 return;
681 }
682
683 /* Send the data to the display */
684 rect.x = 0;
685 rect.y = 0;
686 rect.w = texture->w;
687 rect.h = texture->h;
688 data->renderer->RenderCopy(data->renderer, texture, &rect, &rect);
689 data->renderer->RenderPresent(data->renderer);
690 }
691
692 static void
693 SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
694 {
695 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
696 SDL_SW_DestroyYUVTexture((SDL_SW_YUVTexture *) texture->driverdata);
697 } else {
698 SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
699
700 SDL_FreeSurface(surface);
701 }
702 }
703
704 static void
705 SW_DestroyRenderer(SDL_Renderer * renderer)
706 {
707 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
708 SDL_Window *window = renderer->window;
709
710 if (data) {
711 if (data->texture) {
712 DestroyTexture(data->renderer, data->texture);
713 }
714 if (data->surface.format) {
715 SDL_FreeFormat(data->surface.format);
716 }
717 if (data->renderer) {
718 data->renderer->DestroyRenderer(data->renderer);
719 }
720 SDL_FreeDirtyRects(&data->dirty);
721 SDL_free(data);
722 }
723 SDL_free(renderer);
724 }
725
726 /* vi: set ts=4 sw=4 expandtab: */