SDL  2.0
SDL_render_sw.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #if !SDL_RENDER_DISABLED
24 
25 #include "../SDL_sysrender.h"
26 #include "SDL_render_sw_c.h"
27 #include "SDL_hints.h"
28 
29 #include "SDL_draw.h"
30 #include "SDL_blendfillrect.h"
31 #include "SDL_blendline.h"
32 #include "SDL_blendpoint.h"
33 #include "SDL_drawline.h"
34 #include "SDL_drawpoint.h"
35 #include "SDL_rotate.h"
36 
37 /* SDL surface based renderer implementation */
38 
41  const SDL_WindowEvent *event);
42 static int SW_GetOutputSize(SDL_Renderer * renderer, int *w, int *h);
51  const SDL_Rect * rect, const void *pixels,
52  int pitch);
54  const SDL_Rect * rect, void **pixels, int *pitch);
61  const SDL_FPoint * points, int count);
63  const SDL_FPoint * points, int count);
65  const SDL_FRect * rects, int count);
67  const SDL_Rect * srcrect, const SDL_FRect * dstrect);
69  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
70  const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip);
72  Uint32 format, void * pixels, int pitch);
76 
77 
80  {
81  "software",
83  8,
84  {
93  },
94  0,
95  0}
96 };
97 
98 typedef struct
99 {
102 } SW_RenderData;
103 
104 
105 static SDL_Surface *
107 {
109 
110  if (!data->surface) {
111  data->surface = data->window;
112  }
113  if (!data->surface) {
115  if (surface) {
116  data->surface = data->window = surface;
117 
120  }
121  }
122  return data->surface;
123 }
124 
125 SDL_Renderer *
127 {
130 
131  if (!surface) {
132  SDL_SetError("Can't create renderer for NULL surface");
133  return NULL;
134  }
135 
136  renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
137  if (!renderer) {
138  SDL_OutOfMemory();
139  return NULL;
140  }
141 
142  data = (SW_RenderData *) SDL_calloc(1, sizeof(*data));
143  if (!data) {
145  SDL_OutOfMemory();
146  return NULL;
147  }
148  data->surface = surface;
149  data->window = surface;
150 
175 
177 
178  return renderer;
179 }
180 
181 SDL_Renderer *
183 {
185 
187  if (!surface) {
188  return NULL;
189  }
191 }
192 
193 static void
195 {
197 
198  if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
199  data->surface = NULL;
200  data->window = NULL;
201  }
202 }
203 
204 static int
206 {
208 
209  if (surface) {
210  if (w) {
211  *w = surface->w;
212  }
213  if (h) {
214  *h = surface->h;
215  }
216  return 0;
217  } else {
218  SDL_SetError("Software renderer doesn't have an output surface");
219  return -1;
220  }
221 }
222 
223 static int
225 {
226  int bpp;
227  Uint32 Rmask, Gmask, Bmask, Amask;
228 
230  (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
231  return SDL_SetError("Unknown texture format");
232  }
233 
234  texture->driverdata =
235  SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask,
236  Bmask, Amask);
237  SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g,
238  texture->b);
239  SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a);
240  SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode);
241 
242  /* Only RLE encode textures without an alpha channel since the RLE coder
243  * discards the color values of pixels with an alpha value of zero.
244  */
245  if (texture->access == SDL_TEXTUREACCESS_STATIC && !Amask) {
246  SDL_SetSurfaceRLE(texture->driverdata, 1);
247  }
248 
249  if (!texture->driverdata) {
250  return -1;
251  }
252  return 0;
253 }
254 
255 static int
257 {
258  SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
259  /* If the color mod is ever enabled (non-white), permanently disable RLE (which doesn't support
260  * color mod) to avoid potentially frequent RLE encoding/decoding.
261  */
262  if ((texture->r & texture->g & texture->b) != 255) {
264  }
266  texture->b);
267 }
268 
269 static int
271 {
272  SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
273  /* If the texture ever has multiple alpha values (surface alpha plus alpha channel), permanently
274  * disable RLE (which doesn't support this) to avoid potentially frequent RLE encoding/decoding.
275  */
276  if (texture->a != 255 && surface->format->Amask) {
278  }
280 }
281 
282 static int
284 {
285  SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
286  /* If add or mod blending are ever enabled, permanently disable RLE (which doesn't support
287  * them) to avoid potentially frequent RLE encoding/decoding.
288  */
289  if ((texture->blendMode == SDL_BLENDMODE_ADD || texture->blendMode == SDL_BLENDMODE_MOD)) {
291  }
292  return SDL_SetSurfaceBlendMode(surface, texture->blendMode);
293 }
294 
295 static int
297  const SDL_Rect * rect, const void *pixels, int pitch)
298 {
299  SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
300  Uint8 *src, *dst;
301  int row;
302  size_t length;
303 
304  if(SDL_MUSTLOCK(surface))
306  src = (Uint8 *) pixels;
307  dst = (Uint8 *) surface->pixels +
308  rect->y * surface->pitch +
309  rect->x * surface->format->BytesPerPixel;
310  length = rect->w * surface->format->BytesPerPixel;
311  for (row = 0; row < rect->h; ++row) {
313  src += pitch;
314  dst += surface->pitch;
315  }
316  if(SDL_MUSTLOCK(surface))
318  return 0;
319 }
320 
321 static int
323  const SDL_Rect * rect, void **pixels, int *pitch)
324 {
325  SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
326 
327  *pixels =
328  (void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch +
329  rect->x * surface->format->BytesPerPixel);
330  *pitch = surface->pitch;
331  return 0;
332 }
333 
334 static void
336 {
337 }
338 
339 static int
341 {
343 
344  if (texture ) {
345  data->surface = (SDL_Surface *) texture->driverdata;
346  } else {
347  data->surface = data->window;
348  }
349  return 0;
350 }
351 
352 static int
354 {
356  SDL_Surface *surface = data->surface;
357 
358  if (!surface) {
359  /* We'll update the viewport after we recreate the surface */
360  return 0;
361  }
362 
363  SDL_SetClipRect(data->surface, &renderer->viewport);
364  return 0;
365 }
366 
367 static int
369 {
371  SDL_Surface *surface = data->surface;
372  if (surface) {
373  if (renderer->clipping_enabled) {
374  SDL_Rect clip_rect;
375  clip_rect = renderer->clip_rect;
376  clip_rect.x += renderer->viewport.x;
377  clip_rect.y += renderer->viewport.y;
378  SDL_IntersectRect(&renderer->viewport, &clip_rect, &clip_rect);
379  SDL_SetClipRect(surface, &clip_rect);
380  } else {
382  }
383  }
384  return 0;
385 }
386 
387 static int
389 {
391  Uint32 color;
392  SDL_Rect clip_rect;
393 
394  if (!surface) {
395  return -1;
396  }
397 
398  color = SDL_MapRGBA(surface->format,
400 
401  /* By definition the clear ignores the clip rect */
402  clip_rect = surface->clip_rect;
405  SDL_SetClipRect(surface, &clip_rect);
406  return 0;
407 }
408 
409 static int
411  int count)
412 {
414  SDL_Point *final_points;
415  int i, status;
416 
417  if (!surface) {
418  return -1;
419  }
420 
421  final_points = SDL_stack_alloc(SDL_Point, count);
422  if (!final_points) {
423  return SDL_OutOfMemory();
424  }
425  if (renderer->viewport.x || renderer->viewport.y) {
426  int x = renderer->viewport.x;
427  int y = renderer->viewport.y;
428 
429  for (i = 0; i < count; ++i) {
430  final_points[i].x = (int)(x + points[i].x);
431  final_points[i].y = (int)(y + points[i].y);
432  }
433  } else {
434  for (i = 0; i < count; ++i) {
435  final_points[i].x = (int)points[i].x;
436  final_points[i].y = (int)points[i].y;
437  }
438  }
439 
440  /* Draw the points! */
442  Uint32 color = SDL_MapRGBA(surface->format,
443  renderer->r, renderer->g, renderer->b,
444  renderer->a);
445 
446  status = SDL_DrawPoints(surface, final_points, count, color);
447  } else {
448  status = SDL_BlendPoints(surface, final_points, count,
450  renderer->r, renderer->g, renderer->b,
451  renderer->a);
452  }
453  SDL_stack_free(final_points);
454 
455  return status;
456 }
457 
458 static int
460  int count)
461 {
463  SDL_Point *final_points;
464  int i, status;
465 
466  if (!surface) {
467  return -1;
468  }
469 
470  final_points = SDL_stack_alloc(SDL_Point, count);
471  if (!final_points) {
472  return SDL_OutOfMemory();
473  }
474  if (renderer->viewport.x || renderer->viewport.y) {
475  int x = renderer->viewport.x;
476  int y = renderer->viewport.y;
477 
478  for (i = 0; i < count; ++i) {
479  final_points[i].x = (int)(x + points[i].x);
480  final_points[i].y = (int)(y + points[i].y);
481  }
482  } else {
483  for (i = 0; i < count; ++i) {
484  final_points[i].x = (int)points[i].x;
485  final_points[i].y = (int)points[i].y;
486  }
487  }
488 
489  /* Draw the lines! */
491  Uint32 color = SDL_MapRGBA(surface->format,
492  renderer->r, renderer->g, renderer->b,
493  renderer->a);
494 
495  status = SDL_DrawLines(surface, final_points, count, color);
496  } else {
497  status = SDL_BlendLines(surface, final_points, count,
499  renderer->r, renderer->g, renderer->b,
500  renderer->a);
501  }
502  SDL_stack_free(final_points);
503 
504  return status;
505 }
506 
507 static int
509 {
511  SDL_Rect *final_rects;
512  int i, status;
513 
514  if (!surface) {
515  return -1;
516  }
517 
518  final_rects = SDL_stack_alloc(SDL_Rect, count);
519  if (!final_rects) {
520  return SDL_OutOfMemory();
521  }
522  if (renderer->viewport.x || renderer->viewport.y) {
523  int x = renderer->viewport.x;
524  int y = renderer->viewport.y;
525 
526  for (i = 0; i < count; ++i) {
527  final_rects[i].x = (int)(x + rects[i].x);
528  final_rects[i].y = (int)(y + rects[i].y);
529  final_rects[i].w = SDL_max((int)rects[i].w, 1);
530  final_rects[i].h = SDL_max((int)rects[i].h, 1);
531  }
532  } else {
533  for (i = 0; i < count; ++i) {
534  final_rects[i].x = (int)rects[i].x;
535  final_rects[i].y = (int)rects[i].y;
536  final_rects[i].w = SDL_max((int)rects[i].w, 1);
537  final_rects[i].h = SDL_max((int)rects[i].h, 1);
538  }
539  }
540 
542  Uint32 color = SDL_MapRGBA(surface->format,
543  renderer->r, renderer->g, renderer->b,
544  renderer->a);
545  status = SDL_FillRects(surface, final_rects, count, color);
546  } else {
547  status = SDL_BlendFillRects(surface, final_rects, count,
549  renderer->r, renderer->g, renderer->b,
550  renderer->a);
551  }
552  SDL_stack_free(final_rects);
553 
554  return status;
555 }
556 
557 static int
559  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
560 {
562  SDL_Surface *src = (SDL_Surface *) texture->driverdata;
563  SDL_Rect final_rect;
564 
565  if (!surface) {
566  return -1;
567  }
568 
569  if (renderer->viewport.x || renderer->viewport.y) {
570  final_rect.x = (int)(renderer->viewport.x + dstrect->x);
571  final_rect.y = (int)(renderer->viewport.y + dstrect->y);
572  } else {
573  final_rect.x = (int)dstrect->x;
574  final_rect.y = (int)dstrect->y;
575  }
576  final_rect.w = (int)dstrect->w;
577  final_rect.h = (int)dstrect->h;
578 
579  if ( srcrect->w == final_rect.w && srcrect->h == final_rect.h ) {
580  return SDL_BlitSurface(src, srcrect, surface, &final_rect);
581  } else {
582  /* If scaling is ever done, permanently disable RLE (which doesn't support scaling)
583  * to avoid potentially frequent RLE encoding/decoding.
584  */
586  return SDL_BlitScaled(src, srcrect, surface, &final_rect);
587  }
588 }
589 
590 static int
592  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
593  const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip)
594 {
596  SDL_Surface *src = (SDL_Surface *) texture->driverdata;
597  SDL_Rect final_rect, tmp_rect;
598  SDL_Surface *src_clone, *src_rotated, *src_scaled;
599  SDL_Surface *mask = NULL, *mask_rotated = NULL;
600  int retval = 0, dstwidth, dstheight, abscenterx, abscentery;
601  double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y;
602  SDL_BlendMode blendmode;
603  Uint8 alphaMod, rMod, gMod, bMod;
604  int applyModulation = SDL_FALSE;
605  int blitRequired = SDL_FALSE;
606  int isOpaque = SDL_FALSE;
607 
608  if (!surface) {
609  return -1;
610  }
611 
612  if (renderer->viewport.x || renderer->viewport.y) {
613  final_rect.x = (int)(renderer->viewport.x + dstrect->x);
614  final_rect.y = (int)(renderer->viewport.y + dstrect->y);
615  } else {
616  final_rect.x = (int)dstrect->x;
617  final_rect.y = (int)dstrect->y;
618  }
619  final_rect.w = (int)dstrect->w;
620  final_rect.h = (int)dstrect->h;
621 
622  tmp_rect = final_rect;
623  tmp_rect.x = 0;
624  tmp_rect.y = 0;
625 
626  /* It is possible to encounter an RLE encoded surface here and locking it is
627  * necessary because this code is going to access the pixel buffer directly.
628  */
629  if (SDL_MUSTLOCK(src)) {
631  }
632 
633  /* Clone the source surface but use its pixel buffer directly.
634  * The original source surface must be treated as read-only.
635  */
636  src_clone = SDL_CreateRGBSurfaceFrom(src->pixels, src->w, src->h, src->format->BitsPerPixel, src->pitch,
637  src->format->Rmask, src->format->Gmask,
638  src->format->Bmask, src->format->Amask);
639  if (src_clone == NULL) {
640  if (SDL_MUSTLOCK(src)) {
642  }
643  return -1;
644  }
645 
646  SDL_GetSurfaceBlendMode(src, &blendmode);
647  SDL_GetSurfaceAlphaMod(src, &alphaMod);
648  SDL_GetSurfaceColorMod(src, &rMod, &gMod, &bMod);
649 
650  /* SDLgfx_rotateSurface only accepts 32-bit surfaces with a 8888 layout. Everything else has to be converted. */
651  if (src->format->BitsPerPixel != 32 || SDL_PIXELLAYOUT(src->format->format) != SDL_PACKEDLAYOUT_8888 || !src->format->Amask) {
652  blitRequired = SDL_TRUE;
653  }
654 
655  /* If scaling and cropping is necessary, it has to be taken care of before the rotation. */
656  if (!(srcrect->w == final_rect.w && srcrect->h == final_rect.h && srcrect->x == 0 && srcrect->y == 0)) {
657  blitRequired = SDL_TRUE;
658  }
659 
660  /* srcrect is not selecting the whole src surface, so cropping is needed */
661  if (!(srcrect->w == src->w && srcrect->h == src->h && srcrect->x == 0 && srcrect->y == 0)) {
662  blitRequired = SDL_TRUE;
663  }
664 
665  /* The color and alpha modulation has to be applied before the rotation when using the NONE and MOD blend modes. */
666  if ((blendmode == SDL_BLENDMODE_NONE || blendmode == SDL_BLENDMODE_MOD) && (alphaMod & rMod & gMod & bMod) != 255) {
667  applyModulation = SDL_TRUE;
668  SDL_SetSurfaceAlphaMod(src_clone, alphaMod);
669  SDL_SetSurfaceColorMod(src_clone, rMod, gMod, bMod);
670  }
671 
672  /* Opaque surfaces are much easier to handle with the NONE blend mode. */
673  if (blendmode == SDL_BLENDMODE_NONE && !src->format->Amask && alphaMod == 255) {
674  isOpaque = SDL_TRUE;
675  }
676 
677  /* The NONE blend mode requires a mask for non-opaque surfaces. This mask will be used
678  * to clear the pixels in the destination surface. The other steps are explained below.
679  */
680  if (blendmode == SDL_BLENDMODE_NONE && !isOpaque) {
681  mask = SDL_CreateRGBSurface(0, final_rect.w, final_rect.h, 32,
682  0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
683  if (mask == NULL) {
684  retval = -1;
685  } else {
687  }
688  }
689 
690  /* Create a new surface should there be a format mismatch or if scaling, cropping,
691  * or modulation is required. It's possible to use the source surface directly otherwise.
692  */
693  if (!retval && (blitRequired || applyModulation)) {
694  SDL_Rect scale_rect = tmp_rect;
695  src_scaled = SDL_CreateRGBSurface(0, final_rect.w, final_rect.h, 32,
696  0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
697  if (src_scaled == NULL) {
698  retval = -1;
699  } else {
701  retval = SDL_BlitScaled(src_clone, srcrect, src_scaled, &scale_rect);
702  SDL_FreeSurface(src_clone);
703  src_clone = src_scaled;
704  src_scaled = NULL;
705  }
706  }
707 
708  /* SDLgfx_rotateSurface is going to make decisions depending on the blend mode. */
709  SDL_SetSurfaceBlendMode(src_clone, blendmode);
710 
711  if (!retval) {
712  SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, &dstwidth, &dstheight, &cangle, &sangle);
713  src_rotated = SDLgfx_rotateSurface(src_clone, angle, dstwidth/2, dstheight/2, (texture->scaleMode == SDL_ScaleModeNearest) ? 0 : 1, flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle);
714  if (src_rotated == NULL) {
715  retval = -1;
716  }
717  if (!retval && mask != NULL) {
718  /* The mask needed for the NONE blend mode gets rotated with the same parameters. */
719  mask_rotated = SDLgfx_rotateSurface(mask, angle, dstwidth/2, dstheight/2, SDL_FALSE, 0, 0, dstwidth, dstheight, cangle, sangle);
720  if (mask_rotated == NULL) {
721  retval = -1;
722  }
723  }
724  if (!retval) {
725  /* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */
726  abscenterx = final_rect.x + (int)center->x;
727  abscentery = final_rect.y + (int)center->y;
728  /* Compensate the angle inversion to match the behaviour of the other backends */
729  sangle = -sangle;
730 
731  /* Top Left */
732  px = final_rect.x - abscenterx;
733  py = final_rect.y - abscentery;
734  p1x = px * cangle - py * sangle + abscenterx;
735  p1y = px * sangle + py * cangle + abscentery;
736 
737  /* Top Right */
738  px = final_rect.x + final_rect.w - abscenterx;
739  py = final_rect.y - abscentery;
740  p2x = px * cangle - py * sangle + abscenterx;
741  p2y = px * sangle + py * cangle + abscentery;
742 
743  /* Bottom Left */
744  px = final_rect.x - abscenterx;
745  py = final_rect.y + final_rect.h - abscentery;
746  p3x = px * cangle - py * sangle + abscenterx;
747  p3y = px * sangle + py * cangle + abscentery;
748 
749  /* Bottom Right */
750  px = final_rect.x + final_rect.w - abscenterx;
751  py = final_rect.y + final_rect.h - abscentery;
752  p4x = px * cangle - py * sangle + abscenterx;
753  p4y = px * sangle + py * cangle + abscentery;
754 
755  tmp_rect.x = (int)MIN(MIN(p1x, p2x), MIN(p3x, p4x));
756  tmp_rect.y = (int)MIN(MIN(p1y, p2y), MIN(p3y, p4y));
757  tmp_rect.w = dstwidth;
758  tmp_rect.h = dstheight;
759 
760  /* The NONE blend mode needs some special care with non-opaque surfaces.
761  * Other blend modes or opaque surfaces can be blitted directly.
762  */
763  if (blendmode != SDL_BLENDMODE_NONE || isOpaque) {
764  if (applyModulation == SDL_FALSE) {
765  /* If the modulation wasn't already applied, make it happen now. */
766  SDL_SetSurfaceAlphaMod(src_rotated, alphaMod);
767  SDL_SetSurfaceColorMod(src_rotated, rMod, gMod, bMod);
768  }
769  retval = SDL_BlitSurface(src_rotated, NULL, surface, &tmp_rect);
770  } else {
771  /* The NONE blend mode requires three steps to get the pixels onto the destination surface.
772  * First, the area where the rotated pixels will be blitted to get set to zero.
773  * This is accomplished by simply blitting a mask with the NONE blend mode.
774  * The colorkey set by the rotate function will discard the correct pixels.
775  */
776  SDL_Rect mask_rect = tmp_rect;
778  retval = SDL_BlitSurface(mask_rotated, NULL, surface, &mask_rect);
779  if (!retval) {
780  /* The next step copies the alpha value. This is done with the BLEND blend mode and
781  * by modulating the source colors with 0. Since the destination is all zeros, this
782  * will effectively set the destination alpha to the source alpha.
783  */
784  SDL_SetSurfaceColorMod(src_rotated, 0, 0, 0);
785  mask_rect = tmp_rect;
786  retval = SDL_BlitSurface(src_rotated, NULL, surface, &mask_rect);
787  if (!retval) {
788  /* The last step gets the color values in place. The ADD blend mode simply adds them to
789  * the destination (where the color values are all zero). However, because the ADD blend
790  * mode modulates the colors with the alpha channel, a surface without an alpha mask needs
791  * to be created. This makes all source pixels opaque and the colors get copied correctly.
792  */
793  SDL_Surface *src_rotated_rgb;
794  src_rotated_rgb = SDL_CreateRGBSurfaceFrom(src_rotated->pixels, src_rotated->w, src_rotated->h,
795  src_rotated->format->BitsPerPixel, src_rotated->pitch,
796  src_rotated->format->Rmask, src_rotated->format->Gmask,
797  src_rotated->format->Bmask, 0);
798  if (src_rotated_rgb == NULL) {
799  retval = -1;
800  } else {
801  SDL_SetSurfaceBlendMode(src_rotated_rgb, SDL_BLENDMODE_ADD);
802  retval = SDL_BlitSurface(src_rotated_rgb, NULL, surface, &tmp_rect);
803  SDL_FreeSurface(src_rotated_rgb);
804  }
805  }
806  }
807  SDL_FreeSurface(mask_rotated);
808  }
809  if (src_rotated != NULL) {
810  SDL_FreeSurface(src_rotated);
811  }
812  }
813  }
814 
815  if (SDL_MUSTLOCK(src)) {
817  }
818  if (mask != NULL) {
820  }
821  if (src_clone != NULL) {
822  SDL_FreeSurface(src_clone);
823  }
824  return retval;
825 }
826 
827 static int
829  Uint32 format, void * pixels, int pitch)
830 {
832  Uint32 src_format;
833  void *src_pixels;
834 
835  if (!surface) {
836  return -1;
837  }
838 
839  /* NOTE: The rect is already adjusted according to the viewport by
840  * SDL_RenderReadPixels.
841  */
842 
843  if (rect->x < 0 || rect->x+rect->w > surface->w ||
844  rect->y < 0 || rect->y+rect->h > surface->h) {
845  return SDL_SetError("Tried to read outside of surface bounds");
846  }
847 
848  src_format = surface->format->format;
849  src_pixels = (void*)((Uint8 *) surface->pixels +
850  rect->y * surface->pitch +
851  rect->x * surface->format->BytesPerPixel);
852 
853  return SDL_ConvertPixels(rect->w, rect->h,
854  src_format, src_pixels, surface->pitch,
855  format, pixels, pitch);
856 }
857 
858 static void
860 {
862 
863  if (window) {
865  }
866 }
867 
868 static void
870 {
871  SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
872 
874 }
875 
876 static void
878 {
880 
881  SDL_free(data);
883 }
884 
885 #endif /* !SDL_RENDER_DISABLED */
886 
887 /* vi: set ts=4 sw=4 expandtab: */
SDL_UnlockSurface
#define SDL_UnlockSurface
Definition: SDL_dynapi_overrides.h:449
SDL_PIXELFORMAT_ARGB8888
@ SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:248
SDL_Renderer::blendMode
SDL_BlendMode blendMode
Definition: SDL_sysrender.h:179
SW_CreateRendererForSurface
SDL_Renderer * SW_CreateRendererForSurface(SDL_Surface *surface)
Definition: SDL_render_sw.c:126
format
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
SW_DestroyTexture
static void SW_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_render_sw.c:869
points
GLfixed GLfixed GLint GLint GLfixed points
Definition: SDL_opengl_glext.h:4558
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179
SDL_Point::x
int x
Definition: SDL_rect.h:50
SDL_blendline.h
SW_UpdateViewport
static int SW_UpdateViewport(SDL_Renderer *renderer)
Definition: SDL_render_sw.c:353
mask
GLenum GLint GLuint mask
Definition: SDL_opengl_glext.h:657
SDL_MapRGBA
#define SDL_MapRGBA
Definition: SDL_dynapi_overrides.h:287
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:70
SDL_Renderer::UpdateClipRect
int(* UpdateClipRect)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:112
SW_RenderFillRects
static int SW_RenderFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
Definition: SDL_render_sw.c:508
SDL_PIXELFORMAT_BGRA8888
@ SDL_PIXELFORMAT_BGRA8888
Definition: SDL_pixels.h:257
SDL_BlendFillRects
int SDL_BlendFillRects(SDL_Surface *dst, const SDL_Rect *rects, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Definition: SDL_blendfillrect.c:263
SDL_FPoint::x
float x
Definition: SDL_sysrender.h:44
SDL_FillRects
#define SDL_FillRects
Definition: SDL_dynapi_overrides.h:467
SDL_FRect::h
float h
Definition: SDL_sysrender.h:53
NULL
#define NULL
Definition: begin_code.h:164
SDL_ScaleModeNearest
@ SDL_ScaleModeNearest
Definition: SDL_sysrender.h:37
surface
EGLSurface surface
Definition: eglext.h:248
SDL_Renderer::SetRenderTarget
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:110
SDL_PIXELLAYOUT
#define SDL_PIXELLAYOUT(X)
Definition: SDL_pixels.h:126
SDL_Renderer::g
Uint8 g
Definition: SDL_sysrender.h:178
SW_SetTextureBlendMode
static int SW_SetTextureBlendMode(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_render_sw.c:283
SDL_render_sw_c.h
count
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
SDL_PACKEDLAYOUT_8888
@ SDL_PACKEDLAYOUT_8888
Definition: SDL_pixels.h:112
SDL_Renderer::SetTextureBlendMode
int(* SetTextureBlendMode)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:97
SW_RenderDriver
SDL_RenderDriver SW_RenderDriver
Definition: SDL_render_sw.c:78
SDL_MUSTLOCK
#define SDL_MUSTLOCK(S)
Definition: SDL_surface.h:61
SDL_IntersectRect
#define SDL_IntersectRect
Definition: SDL_dynapi_overrides.h:294
SW_SetTextureColorMod
static int SW_SetTextureColorMod(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_render_sw.c:256
SDL_Renderer::RenderFillRects
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
Definition: SDL_sysrender.h:118
SW_RenderClear
static int SW_RenderClear(SDL_Renderer *renderer)
Definition: SDL_render_sw.c:388
SDL_RenderDriver
Definition: SDL_sysrender.h:186
SDL_FRect::x
float x
Definition: SDL_sysrender.h:50
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_Renderer::UpdateViewport
int(* UpdateViewport)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:111
SDL_Renderer::WindowEvent
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Definition: SDL_sysrender.h:89
SW_CreateRenderer
static SDL_Renderer * SW_CreateRenderer(SDL_Window *window, Uint32 flags)
Definition: SDL_render_sw.c:182
SDL_FPoint::y
float y
Definition: SDL_sysrender.h:45
SDL_BlendLines
int SDL_BlendLines(SDL_Surface *dst, const SDL_Point *points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Definition: SDL_blendline.c:733
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1946
length
GLuint GLsizei GLsizei * length
Definition: SDL_opengl_glext.h:669
SDL_GetSurfaceBlendMode
#define SDL_GetSurfaceBlendMode
Definition: SDL_dynapi_overrides.h:460
SDL_Rect::x
int x
Definition: SDL_rect.h:66
SW_RenderReadPixels
static int SW_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
Definition: SDL_render_sw.c:828
SW_RenderDrawPoints
static int SW_RenderDrawPoints(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Definition: SDL_render_sw.c:410
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
SDL_Rect::w
int w
Definition: SDL_rect.h:67
row
GLenum GLenum void * row
Definition: SDL_opengl_glext.h:3138
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:74
SDL_stack_alloc
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:354
SDL_UpdateWindowSurface
#define SDL_UpdateWindowSurface
Definition: SDL_dynapi_overrides.h:541
SDL_BlendPoints
int SDL_BlendPoints(SDL_Surface *dst, const SDL_Point *points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Definition: SDL_blendpoint.c:257
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1737
SDL_PIXELFORMAT_BGR888
@ SDL_PIXELFORMAT_BGR888
Definition: SDL_pixels.h:242
SW_RenderDrawLines
static int SW_RenderDrawLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Definition: SDL_render_sw.c:459
SDL_Surface::pitch
int pitch
Definition: SDL_surface.h:74
SDL_RENDERER_SOFTWARE
@ SDL_RENDERER_SOFTWARE
Definition: SDL_render.h:66
SDL_Renderer::viewport
SDL_Rect viewport
Definition: SDL_sysrender.h:155
SDL_CreateRGBSurfaceFrom
#define SDL_CreateRGBSurfaceFrom
Definition: SDL_dynapi_overrides.h:445
SW_RenderCopy
static int SW_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Definition: SDL_render_sw.c:558
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_Renderer
Definition: SDL_sysrender.h:86
SDL_FPoint
Definition: SDL_sysrender.h:43
SDL_Renderer::driverdata
void * driverdata
Definition: SDL_sysrender.h:181
SDL_FRect::y
float y
Definition: SDL_sysrender.h:51
SDL_DrawPoints
int SDL_DrawPoints(SDL_Surface *dst, const SDL_Point *points, int count, Uint32 color)
Definition: SDL_drawpoint.c:65
SDL_Renderer::b
Uint8 b
Definition: SDL_sysrender.h:178
SDL_FRect::w
float w
Definition: SDL_sysrender.h:52
retval
SDL_bool retval
Definition: testgamecontroller.c:65
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
color
GLuint color
Definition: SDL_opengl_glext.h:1148
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
SDL_Renderer::SetTextureColorMod
int(* SetTextureColorMod)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:93
SDL_Rect::y
int y
Definition: SDL_rect.h:66
SDL_SetSurfaceColorMod
#define SDL_SetSurfaceColorMod
Definition: SDL_dynapi_overrides.h:455
SDL_Rect::h
int h
Definition: SDL_rect.h:67
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
SDL_TEXTUREACCESS_STATIC
@ SDL_TEXTUREACCESS_STATIC
Definition: SDL_render.h:93
SDL_BlitSurface
#define SDL_BlitSurface
Definition: SDL_surface.h:483
SDL_BLENDMODE_NONE
@ SDL_BLENDMODE_NONE
Definition: SDL_blendmode.h:42
SDL_max
#define SDL_max(x, y)
Definition: SDL_stdinc.h:407
SW_SetRenderTarget
static int SW_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_render_sw.c:340
SDL_draw.h
SDL_blendpoint.h
SDL_FLIP_HORIZONTAL
@ SDL_FLIP_HORIZONTAL
Definition: SDL_render.h:114
rect
SDL_Rect rect
Definition: testrelative.c:27
SDL_FreeSurface
#define SDL_FreeSurface
Definition: SDL_dynapi_overrides.h:446
SDL_Renderer::RenderDrawLines
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:116
SW_GetOutputSize
static int SW_GetOutputSize(SDL_Renderer *renderer, int *w, int *h)
Definition: SDL_render_sw.c:205
SDL_rotate.h
SDL_PixelFormatEnumToMasks
#define SDL_PixelFormatEnumToMasks
Definition: SDL_dynapi_overrides.h:278
SDL_Renderer::RenderClear
int(* RenderClear)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:113
SW_RenderCopyEx
static int SW_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
Definition: SDL_render_sw.c:591
SW_RenderData
Definition: SDL_render_sw.c:99
SDL_PIXELFORMAT_RGB555
@ SDL_PIXELFORMAT_RGB555
Definition: SDL_pixels.h:194
SDL_WINDOWEVENT_SIZE_CHANGED
@ SDL_WINDOWEVENT_SIZE_CHANGED
Definition: SDL_video.h:156
SDL_SetSurfaceRLE
#define SDL_SetSurfaceRLE
Definition: SDL_dynapi_overrides.h:452
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_PIXELFORMAT_RGBA8888
@ SDL_PIXELFORMAT_RGBA8888
Definition: SDL_pixels.h:251
SDL_Renderer::RenderDrawPoints
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:114
SDL_DrawLines
int SDL_DrawLines(SDL_Surface *dst, const SDL_Point *points, int count, Uint32 color)
Definition: SDL_drawline.c:166
SW_UpdateTexture
static int SW_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_render_sw.c:296
pixels
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
SDL_GetWindowSurface
#define SDL_GetWindowSurface
Definition: SDL_dynapi_overrides.h:540
SDL_Renderer::GetOutputSize
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
Definition: SDL_sysrender.h:90
SDL_Renderer::RenderCopy
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Definition: SDL_sysrender.h:120
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_Renderer::SetTextureAlphaMod
int(* SetTextureAlphaMod)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:95
SDL_Renderer::CreateTexture
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:92
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
SDL_drawline.h
SDL_LockSurface
#define SDL_LockSurface
Definition: SDL_dynapi_overrides.h:448
SDL_CreateRGBSurface
#define SDL_CreateRGBSurface
Definition: SDL_dynapi_overrides.h:444
SDL_Renderer::DestroyRenderer
void(* DestroyRenderer)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:130
SDL_Renderer::LockTexture
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_sysrender.h:107
SDL_GetSurfaceAlphaMod
#define SDL_GetSurfaceAlphaMod
Definition: SDL_dynapi_overrides.h:458
SW_RenderData::surface
SDL_Surface * surface
Definition: SDL_render_sw.c:100
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
SW_DestroyRenderer
static void SW_DestroyRenderer(SDL_Renderer *renderer)
Definition: SDL_render_sw.c:877
SDL_Renderer::RenderReadPixels
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
Definition: SDL_sysrender.h:125
SW_RenderData::window
SDL_Surface * window
Definition: SDL_render_sw.c:101
SDL_Renderer::RenderCopyEx
int(* RenderCopyEx)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
Definition: SDL_sysrender.h:122
SDL_blendfillrect.h
src
GLenum src
Definition: SDL_opengl_glext.h:1737
SDL_RendererFlip
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:112
renderer
static SDL_Renderer * renderer
Definition: testaudiocapture.c:21
SDL_FLIP_VERTICAL
@ SDL_FLIP_VERTICAL
Definition: SDL_render.h:115
SDL_stack_free
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:355
SDL_Point
The structure that defines a point.
Definition: SDL_rect.h:49
SDL_Renderer::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:139
SDL_RENDERER_TARGETTEXTURE
@ SDL_RENDERER_TARGETTEXTURE
Definition: SDL_render.h:71
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_Renderer::RenderPresent
void(* RenderPresent)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:127
SW_ActivateRenderer
static SDL_Surface * SW_ActivateRenderer(SDL_Renderer *renderer)
Definition: SDL_render_sw.c:106
SDL_Rect
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:65
SDL_drawpoint.h
SDL_Texture
Definition: SDL_sysrender.h:58
SDL_Renderer::UpdateTexture
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_sysrender.h:99
SDL_hints.h
SDL_PIXELFORMAT_RGB565
@ SDL_PIXELFORMAT_RGB565
Definition: SDL_pixels.h:224
SDL_WindowEvent
Window state change event data (event.window.*)
Definition: SDL_events.h:196
SDL_FRect
Definition: SDL_sysrender.h:49
SDL_SetSurfaceBlendMode
#define SDL_SetSurfaceBlendMode
Definition: SDL_dynapi_overrides.h:459
SDL_GetSurfaceColorMod
#define SDL_GetSurfaceColorMod
Definition: SDL_dynapi_overrides.h:456
SDL_RenderDriver::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:190
SDL_ConvertPixels
#define SDL_ConvertPixels
Definition: SDL_dynapi_overrides.h:465
SW_LockTexture
static int SW_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_render_sw.c:322
angle
GLfloat angle
Definition: SDL_opengl_glext.h:6097
SDLgfx_rotozoomSurfaceSizeTrig
void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle)
Definition: SDL_rotate.c:106
SDL_FillRect
#define SDL_FillRect
Definition: SDL_dynapi_overrides.h:466
SDL_Renderer::clipping_enabled
SDL_bool clipping_enabled
Definition: SDL_sysrender.h:163
SW_SetTextureAlphaMod
static int SW_SetTextureAlphaMod(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_render_sw.c:270
SDLgfx_rotateSurface
SDL_Surface * SDLgfx_rotateSurface(SDL_Surface *src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle)
Definition: SDL_rotate.c:415
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_Renderer::r
Uint8 r
Definition: SDL_sysrender.h:178
SDL_Renderer::a
Uint8 a
Definition: SDL_sysrender.h:178
SDL_PIXELFORMAT_ABGR8888
@ SDL_PIXELFORMAT_ABGR8888
Definition: SDL_pixels.h:254
flags
GLbitfield flags
Definition: SDL_opengl_glext.h:1480
SW_WindowEvent
static void SW_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Definition: SDL_render_sw.c:194
SDL_Renderer::window
SDL_Window * window
Definition: SDL_sysrender.h:142
SW_CreateTexture
static int SW_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_render_sw.c:224
SW_UpdateClipRect
static int SW_UpdateClipRect(SDL_Renderer *renderer)
Definition: SDL_render_sw.c:368
texture
GLenum GLenum GLuint texture
Definition: SDL_opengl_glext.h:1178
SW_RenderPresent
static void SW_RenderPresent(SDL_Renderer *renderer)
Definition: SDL_render_sw.c:859
rects
EGLSurface EGLint * rects
Definition: eglext.h:282
MIN
#define MIN(a, b)
Definition: SDL_rotate.h:26
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SW_UnlockTexture
static void SW_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_render_sw.c:335
SDL_PIXELFORMAT_RGB888
@ SDL_PIXELFORMAT_RGB888
Definition: SDL_pixels.h:236
SDL_BLENDMODE_MOD
@ SDL_BLENDMODE_MOD
Definition: SDL_blendmode.h:50
SDL_Renderer::clip_rect
SDL_Rect clip_rect
Definition: SDL_sysrender.h:159
SDL_BlitScaled
#define SDL_BlitScaled
Definition: SDL_surface.h:512
SDL_Point::y
int y
Definition: SDL_rect.h:51
SDL_SetClipRect
#define SDL_SetClipRect
Definition: SDL_dynapi_overrides.h:461
SDL_BLENDMODE_ADD
@ SDL_BLENDMODE_ADD
Definition: SDL_blendmode.h:47
SDL_BlendMode
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:41
SDL_Renderer::UnlockTexture
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:109
SDL_SetSurfaceAlphaMod
#define SDL_SetSurfaceAlphaMod
Definition: SDL_dynapi_overrides.h:457
SDL_Renderer::DestroyTexture
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:128
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731