zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_render.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 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_config.h"
22 
23 /* The SDL 2D rendering system */
24 
25 #include "SDL_assert.h"
26 #include "SDL_hints.h"
27 #include "SDL_log.h"
28 #include "SDL_render.h"
29 #include "SDL_sysrender.h"
31 
32 
33 #define SDL_WINDOWRENDERDATA "_SDL_WindowRenderData"
34 
35 #define CHECK_RENDERER_MAGIC(renderer, retval) \
36  if (!renderer || renderer->magic != &renderer_magic) { \
37  SDL_SetError("Invalid renderer"); \
38  return retval; \
39  }
40 
41 #define CHECK_TEXTURE_MAGIC(texture, retval) \
42  if (!texture || texture->magic != &texture_magic) { \
43  SDL_SetError("Invalid texture"); \
44  return retval; \
45  }
46 
47 
48 #if !SDL_RENDER_DISABLED
49 static const SDL_RenderDriver *render_drivers[] = {
50 #if SDL_VIDEO_RENDER_D3D
51  &D3D_RenderDriver,
52 #endif
53 #if SDL_VIDEO_RENDER_OGL
54  &GL_RenderDriver,
55 #endif
56 #if SDL_VIDEO_RENDER_OGL_ES2
57  &GLES2_RenderDriver,
58 #endif
59 #if SDL_VIDEO_RENDER_OGL_ES
60  &GLES_RenderDriver,
61 #endif
62 #if SDL_VIDEO_RENDER_DIRECTFB
63  &DirectFB_RenderDriver,
64 #endif
65 #if SDL_VIDEO_RENDER_PSP
66  &PSP_RenderDriver,
67 #endif
69 };
70 #endif /* !SDL_RENDER_DISABLED */
71 
72 static char renderer_magic;
73 static char texture_magic;
74 
75 static int UpdateLogicalSize(SDL_Renderer *renderer);
76 
77 int
79 {
80 #if !SDL_RENDER_DISABLED
81  return SDL_arraysize(render_drivers);
82 #else
83  return 0;
84 #endif
85 }
86 
87 int
89 {
90 #if !SDL_RENDER_DISABLED
92  return SDL_SetError("index must be in the range of 0 - %d",
94  }
95  *info = render_drivers[index]->info;
96  return 0;
97 #else
98  return SDL_SetError("SDL not built with rendering support");
99 #endif
100 }
101 
102 static int
104 {
105  SDL_Renderer *renderer = (SDL_Renderer *)userdata;
106 
107  if (event->type == SDL_WINDOWEVENT) {
108  SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
109  if (window == renderer->window) {
110  if (renderer->WindowEvent) {
111  renderer->WindowEvent(renderer, &event->window);
112  }
113 
114  if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
115  if (renderer->logical_w) {
116  UpdateLogicalSize(renderer);
117  } else {
118  /* Window was resized, reset viewport */
119  int w, h;
120 
121  if (renderer->GetOutputSize) {
122  renderer->GetOutputSize(renderer, &w, &h);
123  } else {
124  SDL_GetWindowSize(renderer->window, &w, &h);
125  }
126 
127  if (renderer->target) {
128  renderer->viewport_backup.x = 0;
129  renderer->viewport_backup.y = 0;
130  renderer->viewport_backup.w = w;
131  renderer->viewport_backup.h = h;
132  } else {
133  renderer->viewport.x = 0;
134  renderer->viewport.y = 0;
135  renderer->viewport.w = w;
136  renderer->viewport.h = h;
137  renderer->UpdateViewport(renderer);
138  }
139  }
140  } else if (event->window.event == SDL_WINDOWEVENT_HIDDEN) {
141  renderer->hidden = SDL_TRUE;
142  } else if (event->window.event == SDL_WINDOWEVENT_SHOWN) {
143  if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)) {
144  renderer->hidden = SDL_FALSE;
145  }
146  } else if (event->window.event == SDL_WINDOWEVENT_MINIMIZED) {
147  renderer->hidden = SDL_TRUE;
148  } else if (event->window.event == SDL_WINDOWEVENT_RESTORED) {
149  if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_HIDDEN)) {
150  renderer->hidden = SDL_FALSE;
151  }
152  }
153  }
154  } else if (event->type == SDL_MOUSEMOTION) {
155  if (renderer->logical_w) {
156  event->motion.x -= renderer->viewport.x;
157  event->motion.y -= renderer->viewport.y;
158  event->motion.x = (int)(event->motion.x / renderer->scale.x);
159  event->motion.y = (int)(event->motion.y / renderer->scale.y);
160  if (event->motion.xrel > 0) {
161  event->motion.xrel = SDL_max(1, (int)(event->motion.xrel / renderer->scale.x));
162  } else if (event->motion.xrel < 0) {
163  event->motion.xrel = SDL_min(-1, (int)(event->motion.xrel / renderer->scale.x));
164  }
165  if (event->motion.yrel > 0) {
166  event->motion.yrel = SDL_max(1, (int)(event->motion.yrel / renderer->scale.y));
167  } else if (event->motion.yrel < 0) {
168  event->motion.yrel = SDL_min(-1, (int)(event->motion.yrel / renderer->scale.y));
169  }
170  }
171  } else if (event->type == SDL_MOUSEBUTTONDOWN ||
172  event->type == SDL_MOUSEBUTTONUP) {
173  if (renderer->logical_w) {
174  event->button.x -= renderer->viewport.x;
175  event->button.y -= renderer->viewport.y;
176  event->button.x = (int)(event->button.x / renderer->scale.x);
177  event->button.y = (int)(event->button.y / renderer->scale.y);
178  }
179  }
180  return 0;
181 }
182 
183 int
185  SDL_Window **window, SDL_Renderer **renderer)
186 {
189  width, height, window_flags);
190  if (!*window) {
191  *renderer = NULL;
192  return -1;
193  }
194 
195  *renderer = SDL_CreateRenderer(*window, -1, 0);
196  if (!*renderer) {
197  return -1;
198  }
199 
200  return 0;
201 }
202 
203 SDL_Renderer *
205 {
206 #if !SDL_RENDER_DISABLED
207  SDL_Renderer *renderer = NULL;
208  int n = SDL_GetNumRenderDrivers();
209  const char *hint;
210 
211  if (!window) {
212  SDL_SetError("Invalid window");
213  return NULL;
214  }
215 
216  if (SDL_GetRenderer(window)) {
217  SDL_SetError("Renderer already associated with window");
218  return NULL;
219  }
220 
222  if (hint) {
223  if (*hint == '0') {
224  flags &= ~SDL_RENDERER_PRESENTVSYNC;
225  } else {
226  flags |= SDL_RENDERER_PRESENTVSYNC;
227  }
228  }
229 
230  if (index < 0) {
232  if (hint) {
233  for (index = 0; index < n; ++index) {
234  const SDL_RenderDriver *driver = render_drivers[index];
235 
236  if (SDL_strcasecmp(hint, driver->info.name) == 0) {
237  /* Create a new renderer instance */
238  renderer = driver->CreateRenderer(window, flags);
239  break;
240  }
241  }
242  }
243 
244  if (!renderer) {
245  for (index = 0; index < n; ++index) {
246  const SDL_RenderDriver *driver = render_drivers[index];
247 
248  if ((driver->info.flags & flags) == flags) {
249  /* Create a new renderer instance */
250  renderer = driver->CreateRenderer(window, flags);
251  if (renderer) {
252  /* Yay, we got one! */
253  break;
254  }
255  }
256  }
257  }
258  if (index == n) {
259  SDL_SetError("Couldn't find matching render driver");
260  return NULL;
261  }
262  } else {
263  if (index >= SDL_GetNumRenderDrivers()) {
264  SDL_SetError("index must be -1 or in the range of 0 - %d",
266  return NULL;
267  }
268  /* Create a new renderer instance */
269  renderer = render_drivers[index]->CreateRenderer(window, flags);
270  }
271 
272  if (renderer) {
273  renderer->magic = &renderer_magic;
274  renderer->window = window;
275  renderer->scale.x = 1.0f;
276  renderer->scale.y = 1.0f;
277 
279  renderer->hidden = SDL_TRUE;
280  } else {
281  renderer->hidden = SDL_FALSE;
282  }
283 
284  SDL_SetWindowData(window, SDL_WINDOWRENDERDATA, renderer);
285 
286  SDL_RenderSetViewport(renderer, NULL);
287 
289 
291  "Created renderer: %s", renderer->info.name);
292  }
293  return renderer;
294 #else
295  SDL_SetError("SDL not built with rendering support");
296  return NULL;
297 #endif
298 }
299 
300 SDL_Renderer *
302 {
303 #if !SDL_RENDER_DISABLED
304  SDL_Renderer *renderer;
305 
306  renderer = SW_CreateRendererForSurface(surface);
307 
308  if (renderer) {
309  renderer->magic = &renderer_magic;
310  renderer->scale.x = 1.0f;
311  renderer->scale.y = 1.0f;
312 
313  SDL_RenderSetViewport(renderer, NULL);
314  }
315  return renderer;
316 #else
317  SDL_SetError("SDL not built with rendering support");
318  return NULL;
319 #endif /* !SDL_RENDER_DISABLED */
320 }
321 
322 SDL_Renderer *
324 {
326 }
327 
328 int
330 {
331  CHECK_RENDERER_MAGIC(renderer, -1);
332 
333  *info = renderer->info;
334  return 0;
335 }
336 
337 int
338 SDL_GetRendererOutputSize(SDL_Renderer * renderer, int *w, int *h)
339 {
340  CHECK_RENDERER_MAGIC(renderer, -1);
341 
342  if (renderer->target) {
343  return SDL_QueryTexture(renderer->target, NULL, NULL, w, h);
344  } else if (renderer->GetOutputSize) {
345  return renderer->GetOutputSize(renderer, w, h);
346  } else if (renderer->window) {
347  SDL_GetWindowSize(renderer->window, w, h);
348  return 0;
349  } else {
350  /* This should never happen */
351  SDL_SetError("Renderer doesn't support querying output size");
352  return -1;
353  }
354 }
355 
356 static SDL_bool
358 {
359  Uint32 i;
360 
361  for (i = 0; i < renderer->info.num_texture_formats; ++i) {
362  if (renderer->info.texture_formats[i] == format) {
363  return SDL_TRUE;
364  }
365  }
366  return SDL_FALSE;
367 }
368 
369 static Uint32
371 {
372  Uint32 i;
373 
374  if (SDL_ISPIXELFORMAT_FOURCC(format)) {
375  /* Look for an exact match */
376  for (i = 0; i < renderer->info.num_texture_formats; ++i) {
377  if (renderer->info.texture_formats[i] == format) {
378  return renderer->info.texture_formats[i];
379  }
380  }
381  } else {
382  SDL_bool hasAlpha = SDL_ISPIXELFORMAT_ALPHA(format);
383 
384  /* We just want to match the first format that has the same channels */
385  for (i = 0; i < renderer->info.num_texture_formats; ++i) {
386  if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) &&
387  SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == hasAlpha) {
388  return renderer->info.texture_formats[i];
389  }
390  }
391  }
392  return renderer->info.texture_formats[0];
393 }
394 
395 SDL_Texture *
396 SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h)
397 {
399 
400  CHECK_RENDERER_MAGIC(renderer, NULL);
401 
402  if (!format) {
403  format = renderer->info.texture_formats[0];
404  }
405  if (SDL_ISPIXELFORMAT_INDEXED(format)) {
406  SDL_SetError("Palettized textures are not supported");
407  return NULL;
408  }
409  if (w <= 0 || h <= 0) {
410  SDL_SetError("Texture dimensions can't be 0");
411  return NULL;
412  }
413  texture = (SDL_Texture *) SDL_calloc(1, sizeof(*texture));
414  if (!texture) {
415  SDL_OutOfMemory();
416  return NULL;
417  }
418  texture->magic = &texture_magic;
419  texture->format = format;
420  texture->access = access;
421  texture->w = w;
422  texture->h = h;
423  texture->r = 255;
424  texture->g = 255;
425  texture->b = 255;
426  texture->a = 255;
427  texture->renderer = renderer;
428  texture->next = renderer->textures;
429  if (renderer->textures) {
430  renderer->textures->prev = texture;
431  }
432  renderer->textures = texture;
433 
434  if (IsSupportedFormat(renderer, format)) {
435  if (renderer->CreateTexture(renderer, texture) < 0) {
436  SDL_DestroyTexture(texture);
437  return 0;
438  }
439  } else {
440  texture->native = SDL_CreateTexture(renderer,
441  GetClosestSupportedFormat(renderer, format),
442  access, w, h);
443  if (!texture->native) {
444  SDL_DestroyTexture(texture);
445  return NULL;
446  }
447 
448  /* Swap textures to have texture before texture->native in the list */
449  texture->native->next = texture->next;
450  if (texture->native->next) {
451  texture->native->next->prev = texture->native;
452  }
453  texture->prev = texture->native->prev;
454  if (texture->prev) {
455  texture->prev->next = texture;
456  }
457  texture->native->prev = texture;
458  texture->next = texture->native;
459  renderer->textures = texture;
460 
461  if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
462  texture->yuv = SDL_SW_CreateYUVTexture(format, w, h);
463  if (!texture->yuv) {
464  SDL_DestroyTexture(texture);
465  return NULL;
466  }
467  } else if (access == SDL_TEXTUREACCESS_STREAMING) {
468  /* The pitch is 4 byte aligned */
469  texture->pitch = (((w * SDL_BYTESPERPIXEL(format)) + 3) & ~3);
470  texture->pixels = SDL_calloc(1, texture->pitch * h);
471  if (!texture->pixels) {
472  SDL_DestroyTexture(texture);
473  return NULL;
474  }
475  }
476  }
477  return texture;
478 }
479 
480 SDL_Texture *
482 {
483  const SDL_PixelFormat *fmt;
484  SDL_bool needAlpha;
485  Uint32 i;
486  Uint32 format;
488 
489  CHECK_RENDERER_MAGIC(renderer, NULL);
490 
491  if (!surface) {
492  SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
493  return NULL;
494  }
495 
496  /* See what the best texture format is */
497  fmt = surface->format;
498  if (fmt->Amask || SDL_GetColorKey(surface, NULL) == 0) {
499  needAlpha = SDL_TRUE;
500  } else {
501  needAlpha = SDL_FALSE;
502  }
503  format = renderer->info.texture_formats[0];
504  for (i = 0; i < renderer->info.num_texture_formats; ++i) {
505  if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) &&
506  SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == needAlpha) {
507  format = renderer->info.texture_formats[i];
508  break;
509  }
510  }
511 
512  texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
513  surface->w, surface->h);
514  if (!texture) {
515  return NULL;
516  }
517 
518  if (format == surface->format->format) {
519  if (SDL_MUSTLOCK(surface)) {
520  SDL_LockSurface(surface);
521  SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
522  SDL_UnlockSurface(surface);
523  } else {
524  SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
525  }
526  } else {
527  SDL_PixelFormat *dst_fmt;
528  SDL_Surface *temp = NULL;
529 
530  /* Set up a destination surface for the texture update */
531  dst_fmt = SDL_AllocFormat(format);
532  temp = SDL_ConvertSurface(surface, dst_fmt, 0);
533  SDL_FreeFormat(dst_fmt);
534  if (temp) {
535  SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
536  SDL_FreeSurface(temp);
537  } else {
538  SDL_DestroyTexture(texture);
539  return NULL;
540  }
541  }
542 
543  {
544  Uint8 r, g, b, a;
545  SDL_BlendMode blendMode;
546 
547  SDL_GetSurfaceColorMod(surface, &r, &g, &b);
548  SDL_SetTextureColorMod(texture, r, g, b);
549 
550  SDL_GetSurfaceAlphaMod(surface, &a);
551  SDL_SetTextureAlphaMod(texture, a);
552 
553  if (SDL_GetColorKey(surface, NULL) == 0) {
554  /* We converted to a texture with alpha format */
556  } else {
557  SDL_GetSurfaceBlendMode(surface, &blendMode);
558  SDL_SetTextureBlendMode(texture, blendMode);
559  }
560  }
561  return texture;
562 }
563 
564 int
566  int *w, int *h)
567 {
568  CHECK_TEXTURE_MAGIC(texture, -1);
569 
570  if (format) {
571  *format = texture->format;
572  }
573  if (access) {
574  *access = texture->access;
575  }
576  if (w) {
577  *w = texture->w;
578  }
579  if (h) {
580  *h = texture->h;
581  }
582  return 0;
583 }
584 
585 int
587 {
588  SDL_Renderer *renderer;
589 
590  CHECK_TEXTURE_MAGIC(texture, -1);
591 
592  renderer = texture->renderer;
593  if (r < 255 || g < 255 || b < 255) {
595  } else {
596  texture->modMode &= ~SDL_TEXTUREMODULATE_COLOR;
597  }
598  texture->r = r;
599  texture->g = g;
600  texture->b = b;
601  if (texture->native) {
602  return SDL_SetTextureColorMod(texture->native, r, g, b);
603  } else if (renderer->SetTextureColorMod) {
604  return renderer->SetTextureColorMod(renderer, texture);
605  } else {
606  return 0;
607  }
608 }
609 
610 int
612  Uint8 * b)
613 {
614  CHECK_TEXTURE_MAGIC(texture, -1);
615 
616  if (r) {
617  *r = texture->r;
618  }
619  if (g) {
620  *g = texture->g;
621  }
622  if (b) {
623  *b = texture->b;
624  }
625  return 0;
626 }
627 
628 int
630 {
631  SDL_Renderer *renderer;
632 
633  CHECK_TEXTURE_MAGIC(texture, -1);
634 
635  renderer = texture->renderer;
636  if (alpha < 255) {
638  } else {
639  texture->modMode &= ~SDL_TEXTUREMODULATE_ALPHA;
640  }
641  texture->a = alpha;
642  if (texture->native) {
643  return SDL_SetTextureAlphaMod(texture->native, alpha);
644  } else if (renderer->SetTextureAlphaMod) {
645  return renderer->SetTextureAlphaMod(renderer, texture);
646  } else {
647  return 0;
648  }
649 }
650 
651 int
653 {
654  CHECK_TEXTURE_MAGIC(texture, -1);
655 
656  if (alpha) {
657  *alpha = texture->a;
658  }
659  return 0;
660 }
661 
662 int
664 {
665  SDL_Renderer *renderer;
666 
667  CHECK_TEXTURE_MAGIC(texture, -1);
668 
669  renderer = texture->renderer;
670  texture->blendMode = blendMode;
671  if (texture->native) {
672  return SDL_SetTextureBlendMode(texture->native, blendMode);
673  } else if (renderer->SetTextureBlendMode) {
674  return renderer->SetTextureBlendMode(renderer, texture);
675  } else {
676  return 0;
677  }
678 }
679 
680 int
682 {
683  CHECK_TEXTURE_MAGIC(texture, -1);
684 
685  if (blendMode) {
686  *blendMode = texture->blendMode;
687  }
688  return 0;
689 }
690 
691 static int
693  const void *pixels, int pitch)
694 {
695  SDL_Texture *native = texture->native;
696  SDL_Rect full_rect;
697 
698  if (SDL_SW_UpdateYUVTexture(texture->yuv, rect, pixels, pitch) < 0) {
699  return -1;
700  }
701 
702  full_rect.x = 0;
703  full_rect.y = 0;
704  full_rect.w = texture->w;
705  full_rect.h = texture->h;
706  rect = &full_rect;
707 
708  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
709  /* We can lock the texture and copy to it */
710  void *native_pixels;
711  int native_pitch;
712 
713  if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
714  return -1;
715  }
716  SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
717  rect->w, rect->h, native_pixels, native_pitch);
718  SDL_UnlockTexture(native);
719  } else {
720  /* Use a temporary buffer for updating */
721  void *temp_pixels;
722  int temp_pitch;
723 
724  temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3);
725  temp_pixels = SDL_malloc(rect->h * temp_pitch);
726  if (!temp_pixels) {
727  return SDL_OutOfMemory();
728  }
729  SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
730  rect->w, rect->h, temp_pixels, temp_pitch);
731  SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch);
732  SDL_free(temp_pixels);
733  }
734  return 0;
735 }
736 
737 static int
739  const void *pixels, int pitch)
740 {
741  SDL_Texture *native = texture->native;
742 
743  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
744  /* We can lock the texture and copy to it */
745  void *native_pixels;
746  int native_pitch;
747 
748  if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
749  return -1;
750  }
751  SDL_ConvertPixels(rect->w, rect->h,
752  texture->format, pixels, pitch,
753  native->format, native_pixels, native_pitch);
754  SDL_UnlockTexture(native);
755  } else {
756  /* Use a temporary buffer for updating */
757  void *temp_pixels;
758  int temp_pitch;
759 
760  temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3);
761  temp_pixels = SDL_malloc(rect->h * temp_pitch);
762  if (!temp_pixels) {
763  return SDL_OutOfMemory();
764  }
765  SDL_ConvertPixels(rect->w, rect->h,
766  texture->format, pixels, pitch,
767  native->format, temp_pixels, temp_pitch);
768  SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch);
769  SDL_free(temp_pixels);
770  }
771  return 0;
772 }
773 
774 int
776  const void *pixels, int pitch)
777 {
778  SDL_Renderer *renderer;
779  SDL_Rect full_rect;
780 
781  CHECK_TEXTURE_MAGIC(texture, -1);
782 
783  if (!pixels) {
784  return SDL_InvalidParamError("pixels");
785  }
786  if (!pitch) {
787  return SDL_InvalidParamError("pitch");
788  }
789 
790  if (!rect) {
791  full_rect.x = 0;
792  full_rect.y = 0;
793  full_rect.w = texture->w;
794  full_rect.h = texture->h;
795  rect = &full_rect;
796  }
797 
798  if (texture->yuv) {
799  return SDL_UpdateTextureYUV(texture, rect, pixels, pitch);
800  } else if (texture->native) {
801  return SDL_UpdateTextureNative(texture, rect, pixels, pitch);
802  } else {
803  renderer = texture->renderer;
804  return renderer->UpdateTexture(renderer, texture, rect, pixels, pitch);
805  }
806 }
807 
808 static int
810  const Uint8 *Yplane, int Ypitch,
811  const Uint8 *Uplane, int Upitch,
812  const Uint8 *Vplane, int Vpitch)
813 {
814  SDL_Texture *native = texture->native;
815  SDL_Rect full_rect;
816 
817  if (SDL_SW_UpdateYUVTexturePlanar(texture->yuv, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch) < 0) {
818  return -1;
819  }
820 
821  full_rect.x = 0;
822  full_rect.y = 0;
823  full_rect.w = texture->w;
824  full_rect.h = texture->h;
825  rect = &full_rect;
826 
827  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
828  /* We can lock the texture and copy to it */
829  void *native_pixels;
830  int native_pitch;
831 
832  if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
833  return -1;
834  }
835  SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
836  rect->w, rect->h, native_pixels, native_pitch);
837  SDL_UnlockTexture(native);
838  } else {
839  /* Use a temporary buffer for updating */
840  void *temp_pixels;
841  int temp_pitch;
842 
843  temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3);
844  temp_pixels = SDL_malloc(rect->h * temp_pitch);
845  if (!temp_pixels) {
846  return SDL_OutOfMemory();
847  }
848  SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
849  rect->w, rect->h, temp_pixels, temp_pitch);
850  SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch);
851  SDL_free(temp_pixels);
852  }
853  return 0;
854 }
855 
857  const Uint8 *Yplane, int Ypitch,
858  const Uint8 *Uplane, int Upitch,
859  const Uint8 *Vplane, int Vpitch)
860 {
861  SDL_Renderer *renderer;
862  SDL_Rect full_rect;
863 
864  CHECK_TEXTURE_MAGIC(texture, -1);
865 
866  if (!Yplane) {
867  return SDL_InvalidParamError("Yplane");
868  }
869  if (!Ypitch) {
870  return SDL_InvalidParamError("Ypitch");
871  }
872  if (!Uplane) {
873  return SDL_InvalidParamError("Uplane");
874  }
875  if (!Upitch) {
876  return SDL_InvalidParamError("Upitch");
877  }
878  if (!Vplane) {
879  return SDL_InvalidParamError("Vplane");
880  }
881  if (!Vpitch) {
882  return SDL_InvalidParamError("Vpitch");
883  }
884 
885  if (texture->format != SDL_PIXELFORMAT_YV12 &&
886  texture->format != SDL_PIXELFORMAT_IYUV) {
887  return SDL_SetError("Texture format must by YV12 or IYUV");
888  }
889 
890  if (!rect) {
891  full_rect.x = 0;
892  full_rect.y = 0;
893  full_rect.w = texture->w;
894  full_rect.h = texture->h;
895  rect = &full_rect;
896  }
897 
898  if (texture->yuv) {
899  return SDL_UpdateTextureYUVPlanar(texture, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
900  } else {
901  SDL_assert(!texture->native);
902  renderer = texture->renderer;
903  SDL_assert(renderer->UpdateTextureYUV);
904  if (renderer->UpdateTextureYUV) {
905  return renderer->UpdateTextureYUV(renderer, texture, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
906  } else {
907  return SDL_Unsupported();
908  }
909  }
910 }
911 
912 static int
914  void **pixels, int *pitch)
915 {
916  return SDL_SW_LockYUVTexture(texture->yuv, rect, pixels, pitch);
917 }
918 
919 static int
921  void **pixels, int *pitch)
922 {
923  texture->locked_rect = *rect;
924  *pixels = (void *) ((Uint8 *) texture->pixels +
925  rect->y * texture->pitch +
926  rect->x * SDL_BYTESPERPIXEL(texture->format));
927  *pitch = texture->pitch;
928  return 0;
929 }
930 
931 int
933  void **pixels, int *pitch)
934 {
935  SDL_Renderer *renderer;
936  SDL_Rect full_rect;
937 
938  CHECK_TEXTURE_MAGIC(texture, -1);
939 
940  if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
941  return SDL_SetError("SDL_LockTexture(): texture must be streaming");
942  }
943 
944  if (!rect) {
945  full_rect.x = 0;
946  full_rect.y = 0;
947  full_rect.w = texture->w;
948  full_rect.h = texture->h;
949  rect = &full_rect;
950  }
951 
952  if (texture->yuv) {
953  return SDL_LockTextureYUV(texture, rect, pixels, pitch);
954  } else if (texture->native) {
955  return SDL_LockTextureNative(texture, rect, pixels, pitch);
956  } else {
957  renderer = texture->renderer;
958  return renderer->LockTexture(renderer, texture, rect, pixels, pitch);
959  }
960 }
961 
962 static void
964 {
965  SDL_Texture *native = texture->native;
966  void *native_pixels;
967  int native_pitch;
968  SDL_Rect rect;
969 
970  rect.x = 0;
971  rect.y = 0;
972  rect.w = texture->w;
973  rect.h = texture->h;
974 
975  if (SDL_LockTexture(native, &rect, &native_pixels, &native_pitch) < 0) {
976  return;
977  }
978  SDL_SW_CopyYUVToRGB(texture->yuv, &rect, native->format,
979  rect.w, rect.h, native_pixels, native_pitch);
980  SDL_UnlockTexture(native);
981 }
982 
983 static void
985 {
986  SDL_Texture *native = texture->native;
987  void *native_pixels;
988  int native_pitch;
989  const SDL_Rect *rect = &texture->locked_rect;
990  const void* pixels = (void *) ((Uint8 *) texture->pixels +
991  rect->y * texture->pitch +
992  rect->x * SDL_BYTESPERPIXEL(texture->format));
993  int pitch = texture->pitch;
994 
995  if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
996  return;
997  }
998  SDL_ConvertPixels(rect->w, rect->h,
999  texture->format, pixels, pitch,
1000  native->format, native_pixels, native_pitch);
1001  SDL_UnlockTexture(native);
1002 }
1003 
1004 void
1006 {
1007  SDL_Renderer *renderer;
1008 
1009  CHECK_TEXTURE_MAGIC(texture, );
1010 
1011  if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
1012  return;
1013  }
1014  if (texture->yuv) {
1015  SDL_UnlockTextureYUV(texture);
1016  } else if (texture->native) {
1017  SDL_UnlockTextureNative(texture);
1018  } else {
1019  renderer = texture->renderer;
1020  renderer->UnlockTexture(renderer, texture);
1021  }
1022 }
1023 
1024 SDL_bool
1026 {
1027  if (!renderer || !renderer->SetRenderTarget) {
1028  return SDL_FALSE;
1029  }
1030  return (renderer->info.flags & SDL_RENDERER_TARGETTEXTURE) != 0;
1031 }
1032 
1033 int
1035 {
1036  if (!SDL_RenderTargetSupported(renderer)) {
1037  return SDL_Unsupported();
1038  }
1039  if (texture == renderer->target) {
1040  /* Nothing to do! */
1041  return 0;
1042  }
1043 
1044  /* texture == NULL is valid and means reset the target to the window */
1045  if (texture) {
1046  CHECK_TEXTURE_MAGIC(texture, -1);
1047  if (renderer != texture->renderer) {
1048  return SDL_SetError("Texture was not created with this renderer");
1049  }
1050  if (texture->access != SDL_TEXTUREACCESS_TARGET) {
1051  return SDL_SetError("Texture not created with SDL_TEXTUREACCESS_TARGET");
1052  }
1053  if (texture->native) {
1054  /* Always render to the native texture */
1055  texture = texture->native;
1056  }
1057  }
1058 
1059  if (texture && !renderer->target) {
1060  /* Make a backup of the viewport */
1061  renderer->viewport_backup = renderer->viewport;
1062  renderer->clip_rect_backup = renderer->clip_rect;
1063  renderer->scale_backup = renderer->scale;
1064  renderer->logical_w_backup = renderer->logical_w;
1065  renderer->logical_h_backup = renderer->logical_h;
1066  }
1067  renderer->target = texture;
1068 
1069  if (renderer->SetRenderTarget(renderer, texture) < 0) {
1070  return -1;
1071  }
1072 
1073  if (texture) {
1074  renderer->viewport.x = 0;
1075  renderer->viewport.y = 0;
1076  renderer->viewport.w = texture->w;
1077  renderer->viewport.h = texture->h;
1078  renderer->scale.x = 1.0f;
1079  renderer->scale.y = 1.0f;
1080  renderer->logical_w = texture->w;
1081  renderer->logical_h = texture->h;
1082  } else {
1083  renderer->viewport = renderer->viewport_backup;
1084  renderer->clip_rect = renderer->clip_rect_backup;
1085  renderer->scale = renderer->scale_backup;
1086  renderer->logical_w = renderer->logical_w_backup;
1087  renderer->logical_h = renderer->logical_h_backup;
1088  }
1089  if (renderer->UpdateViewport(renderer) < 0) {
1090  return -1;
1091  }
1092  if (renderer->UpdateClipRect(renderer) < 0) {
1093  return -1;
1094  }
1095 
1096  /* All set! */
1097  return 0;
1098 }
1099 
1100 SDL_Texture *
1102 {
1103  return renderer->target;
1104 }
1105 
1106 static int
1108 {
1109  int w, h;
1110  float want_aspect;
1111  float real_aspect;
1112  float scale;
1113  SDL_Rect viewport;
1114 
1115  if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) {
1116  return -1;
1117  }
1118 
1119  want_aspect = (float)renderer->logical_w / renderer->logical_h;
1120  real_aspect = (float)w / h;
1121 
1122  /* Clear the scale because we're setting viewport in output coordinates */
1123  SDL_RenderSetScale(renderer, 1.0f, 1.0f);
1124 
1125  if (SDL_fabs(want_aspect-real_aspect) < 0.0001) {
1126  /* The aspect ratios are the same, just scale appropriately */
1127  scale = (float)w / renderer->logical_w;
1128  SDL_RenderSetViewport(renderer, NULL);
1129  } else if (want_aspect > real_aspect) {
1130  /* We want a wider aspect ratio than is available - letterbox it */
1131  scale = (float)w / renderer->logical_w;
1132  viewport.x = 0;
1133  viewport.w = w;
1134  viewport.h = (int)SDL_ceil(renderer->logical_h * scale);
1135  viewport.y = (h - viewport.h) / 2;
1136  SDL_RenderSetViewport(renderer, &viewport);
1137  } else {
1138  /* We want a narrower aspect ratio than is available - use side-bars */
1139  scale = (float)h / renderer->logical_h;
1140  viewport.y = 0;
1141  viewport.h = h;
1142  viewport.w = (int)SDL_ceil(renderer->logical_w * scale);
1143  viewport.x = (w - viewport.w) / 2;
1144  SDL_RenderSetViewport(renderer, &viewport);
1145  }
1146 
1147  /* Set the new scale */
1148  SDL_RenderSetScale(renderer, scale, scale);
1149 
1150  return 0;
1151 }
1152 
1153 int
1155 {
1156  CHECK_RENDERER_MAGIC(renderer, -1);
1157 
1158  if (!w || !h) {
1159  /* Clear any previous logical resolution */
1160  renderer->logical_w = 0;
1161  renderer->logical_h = 0;
1162  SDL_RenderSetViewport(renderer, NULL);
1163  SDL_RenderSetScale(renderer, 1.0f, 1.0f);
1164  return 0;
1165  }
1166 
1167  renderer->logical_w = w;
1168  renderer->logical_h = h;
1169 
1170  return UpdateLogicalSize(renderer);
1171 }
1172 
1173 void
1174 SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h)
1175 {
1176  CHECK_RENDERER_MAGIC(renderer, );
1177 
1178  if (w) {
1179  *w = renderer->logical_w;
1180  }
1181  if (h) {
1182  *h = renderer->logical_h;
1183  }
1184 }
1185 
1186 int
1188 {
1189  CHECK_RENDERER_MAGIC(renderer, -1);
1190 
1191  if (rect) {
1192  renderer->viewport.x = (int)SDL_floor(rect->x * renderer->scale.x);
1193  renderer->viewport.y = (int)SDL_floor(rect->y * renderer->scale.y);
1194  renderer->viewport.w = (int)SDL_ceil(rect->w * renderer->scale.x);
1195  renderer->viewport.h = (int)SDL_ceil(rect->h * renderer->scale.y);
1196  } else {
1197  renderer->viewport.x = 0;
1198  renderer->viewport.y = 0;
1199  if (SDL_GetRendererOutputSize(renderer, &renderer->viewport.w, &renderer->viewport.h) < 0) {
1200  return -1;
1201  }
1202  }
1203  return renderer->UpdateViewport(renderer);
1204 }
1205 
1206 void
1208 {
1209  CHECK_RENDERER_MAGIC(renderer, );
1210 
1211  if (rect) {
1212  rect->x = (int)(renderer->viewport.x / renderer->scale.x);
1213  rect->y = (int)(renderer->viewport.y / renderer->scale.y);
1214  rect->w = (int)(renderer->viewport.w / renderer->scale.x);
1215  rect->h = (int)(renderer->viewport.h / renderer->scale.y);
1216  }
1217 }
1218 
1219 int
1221 {
1222  CHECK_RENDERER_MAGIC(renderer, -1)
1223 
1224  if (rect) {
1225  renderer->clip_rect.x = (int)SDL_floor(rect->x * renderer->scale.x);
1226  renderer->clip_rect.y = (int)SDL_floor(rect->y * renderer->scale.y);
1227  renderer->clip_rect.w = (int)SDL_ceil(rect->w * renderer->scale.x);
1228  renderer->clip_rect.h = (int)SDL_ceil(rect->h * renderer->scale.y);
1229  } else {
1230  SDL_zero(renderer->clip_rect);
1231  }
1232  return renderer->UpdateClipRect(renderer);
1233 }
1234 
1235 void
1237 {
1238  CHECK_RENDERER_MAGIC(renderer, )
1239 
1240  if (rect) {
1241  rect->x = (int)(renderer->clip_rect.x / renderer->scale.x);
1242  rect->y = (int)(renderer->clip_rect.y / renderer->scale.y);
1243  rect->w = (int)(renderer->clip_rect.w / renderer->scale.x);
1244  rect->h = (int)(renderer->clip_rect.h / renderer->scale.y);
1245  }
1246 }
1247 
1248 int
1249 SDL_RenderSetScale(SDL_Renderer * renderer, float scaleX, float scaleY)
1250 {
1251  CHECK_RENDERER_MAGIC(renderer, -1);
1252 
1253  renderer->scale.x = scaleX;
1254  renderer->scale.y = scaleY;
1255  return 0;
1256 }
1257 
1258 void
1259 SDL_RenderGetScale(SDL_Renderer * renderer, float *scaleX, float *scaleY)
1260 {
1261  CHECK_RENDERER_MAGIC(renderer, );
1262 
1263  if (scaleX) {
1264  *scaleX = renderer->scale.x;
1265  }
1266  if (scaleY) {
1267  *scaleY = renderer->scale.y;
1268  }
1269 }
1270 
1271 int
1273  Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1274 {
1275  CHECK_RENDERER_MAGIC(renderer, -1);
1276 
1277  renderer->r = r;
1278  renderer->g = g;
1279  renderer->b = b;
1280  renderer->a = a;
1281  return 0;
1282 }
1283 
1284 int
1286  Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a)
1287 {
1288  CHECK_RENDERER_MAGIC(renderer, -1);
1289 
1290  if (r) {
1291  *r = renderer->r;
1292  }
1293  if (g) {
1294  *g = renderer->g;
1295  }
1296  if (b) {
1297  *b = renderer->b;
1298  }
1299  if (a) {
1300  *a = renderer->a;
1301  }
1302  return 0;
1303 }
1304 
1305 int
1307 {
1308  CHECK_RENDERER_MAGIC(renderer, -1);
1309 
1310  renderer->blendMode = blendMode;
1311  return 0;
1312 }
1313 
1314 int
1316 {
1317  CHECK_RENDERER_MAGIC(renderer, -1);
1318 
1319  *blendMode = renderer->blendMode;
1320  return 0;
1321 }
1322 
1323 int
1325 {
1326  CHECK_RENDERER_MAGIC(renderer, -1);
1327 
1328  /* Don't draw while we're hidden */
1329  if (renderer->hidden) {
1330  return 0;
1331  }
1332  return renderer->RenderClear(renderer);
1333 }
1334 
1335 int
1336 SDL_RenderDrawPoint(SDL_Renderer * renderer, int x, int y)
1337 {
1338  SDL_Point point;
1339 
1340  point.x = x;
1341  point.y = y;
1342  return SDL_RenderDrawPoints(renderer, &point, 1);
1343 }
1344 
1345 static int
1347  const SDL_Point * points, int count)
1348 {
1349  SDL_FRect *frects;
1350  int i;
1351  int status;
1352 
1353  frects = SDL_stack_alloc(SDL_FRect, count);
1354  if (!frects) {
1355  return SDL_OutOfMemory();
1356  }
1357  for (i = 0; i < count; ++i) {
1358  frects[i].x = points[i].x * renderer->scale.x;
1359  frects[i].y = points[i].y * renderer->scale.y;
1360  frects[i].w = renderer->scale.x;
1361  frects[i].h = renderer->scale.y;
1362  }
1363 
1364  status = renderer->RenderFillRects(renderer, frects, count);
1365 
1366  SDL_stack_free(frects);
1367 
1368  return status;
1369 }
1370 
1371 int
1373  const SDL_Point * points, int count)
1374 {
1375  SDL_FPoint *fpoints;
1376  int i;
1377  int status;
1378 
1379  CHECK_RENDERER_MAGIC(renderer, -1);
1380 
1381  if (!points) {
1382  return SDL_SetError("SDL_RenderDrawPoints(): Passed NULL points");
1383  }
1384  if (count < 1) {
1385  return 0;
1386  }
1387  /* Don't draw while we're hidden */
1388  if (renderer->hidden) {
1389  return 0;
1390  }
1391 
1392  if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
1393  return RenderDrawPointsWithRects(renderer, points, count);
1394  }
1395 
1396  fpoints = SDL_stack_alloc(SDL_FPoint, count);
1397  if (!fpoints) {
1398  return SDL_OutOfMemory();
1399  }
1400  for (i = 0; i < count; ++i) {
1401  fpoints[i].x = points[i].x * renderer->scale.x;
1402  fpoints[i].y = points[i].y * renderer->scale.y;
1403  }
1404 
1405  status = renderer->RenderDrawPoints(renderer, fpoints, count);
1406 
1407  SDL_stack_free(fpoints);
1408 
1409  return status;
1410 }
1411 
1412 int
1413 SDL_RenderDrawLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
1414 {
1415  SDL_Point points[2];
1416 
1417  points[0].x = x1;
1418  points[0].y = y1;
1419  points[1].x = x2;
1420  points[1].y = y2;
1421  return SDL_RenderDrawLines(renderer, points, 2);
1422 }
1423 
1424 static int
1426  const SDL_Point * points, int count)
1427 {
1428  SDL_FRect *frect;
1429  SDL_FRect *frects;
1430  SDL_FPoint fpoints[2];
1431  int i, nrects;
1432  int status;
1433 
1434  frects = SDL_stack_alloc(SDL_FRect, count-1);
1435  if (!frects) {
1436  return SDL_OutOfMemory();
1437  }
1438 
1439  status = 0;
1440  nrects = 0;
1441  for (i = 0; i < count-1; ++i) {
1442  if (points[i].x == points[i+1].x) {
1443  int minY = SDL_min(points[i].y, points[i+1].y);
1444  int maxY = SDL_max(points[i].y, points[i+1].y);
1445 
1446  frect = &frects[nrects++];
1447  frect->x = points[i].x * renderer->scale.x;
1448  frect->y = minY * renderer->scale.y;
1449  frect->w = renderer->scale.x;
1450  frect->h = (maxY - minY + 1) * renderer->scale.y;
1451  } else if (points[i].y == points[i+1].y) {
1452  int minX = SDL_min(points[i].x, points[i+1].x);
1453  int maxX = SDL_max(points[i].x, points[i+1].x);
1454 
1455  frect = &frects[nrects++];
1456  frect->x = minX * renderer->scale.x;
1457  frect->y = points[i].y * renderer->scale.y;
1458  frect->w = (maxX - minX + 1) * renderer->scale.x;
1459  frect->h = renderer->scale.y;
1460  } else {
1461  /* FIXME: We can't use a rect for this line... */
1462  fpoints[0].x = points[i].x * renderer->scale.x;
1463  fpoints[0].y = points[i].y * renderer->scale.y;
1464  fpoints[1].x = points[i+1].x * renderer->scale.x;
1465  fpoints[1].y = points[i+1].y * renderer->scale.y;
1466  status += renderer->RenderDrawLines(renderer, fpoints, 2);
1467  }
1468  }
1469 
1470  status += renderer->RenderFillRects(renderer, frects, nrects);
1471 
1472  SDL_stack_free(frects);
1473 
1474  if (status < 0) {
1475  status = -1;
1476  }
1477  return status;
1478 }
1479 
1480 int
1482  const SDL_Point * points, int count)
1483 {
1484  SDL_FPoint *fpoints;
1485  int i;
1486  int status;
1487 
1488  CHECK_RENDERER_MAGIC(renderer, -1);
1489 
1490  if (!points) {
1491  return SDL_SetError("SDL_RenderDrawLines(): Passed NULL points");
1492  }
1493  if (count < 2) {
1494  return 0;
1495  }
1496  /* Don't draw while we're hidden */
1497  if (renderer->hidden) {
1498  return 0;
1499  }
1500 
1501  if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
1502  return RenderDrawLinesWithRects(renderer, points, count);
1503  }
1504 
1505  fpoints = SDL_stack_alloc(SDL_FPoint, count);
1506  if (!fpoints) {
1507  return SDL_OutOfMemory();
1508  }
1509  for (i = 0; i < count; ++i) {
1510  fpoints[i].x = points[i].x * renderer->scale.x;
1511  fpoints[i].y = points[i].y * renderer->scale.y;
1512  }
1513 
1514  status = renderer->RenderDrawLines(renderer, fpoints, count);
1515 
1516  SDL_stack_free(fpoints);
1517 
1518  return status;
1519 }
1520 
1521 int
1522 SDL_RenderDrawRect(SDL_Renderer * renderer, const SDL_Rect * rect)
1523 {
1524  SDL_Rect full_rect;
1525  SDL_Point points[5];
1526 
1527  CHECK_RENDERER_MAGIC(renderer, -1);
1528 
1529  /* If 'rect' == NULL, then outline the whole surface */
1530  if (!rect) {
1531  SDL_RenderGetViewport(renderer, &full_rect);
1532  full_rect.x = 0;
1533  full_rect.y = 0;
1534  rect = &full_rect;
1535  }
1536 
1537  points[0].x = rect->x;
1538  points[0].y = rect->y;
1539  points[1].x = rect->x+rect->w-1;
1540  points[1].y = rect->y;
1541  points[2].x = rect->x+rect->w-1;
1542  points[2].y = rect->y+rect->h-1;
1543  points[3].x = rect->x;
1544  points[3].y = rect->y+rect->h-1;
1545  points[4].x = rect->x;
1546  points[4].y = rect->y;
1547  return SDL_RenderDrawLines(renderer, points, 5);
1548 }
1549 
1550 int
1552  const SDL_Rect * rects, int count)
1553 {
1554  int i;
1555 
1556  CHECK_RENDERER_MAGIC(renderer, -1);
1557 
1558  if (!rects) {
1559  return SDL_SetError("SDL_RenderDrawRects(): Passed NULL rects");
1560  }
1561  if (count < 1) {
1562  return 0;
1563  }
1564 
1565  /* Don't draw while we're hidden */
1566  if (renderer->hidden) {
1567  return 0;
1568  }
1569  for (i = 0; i < count; ++i) {
1570  if (SDL_RenderDrawRect(renderer, &rects[i]) < 0) {
1571  return -1;
1572  }
1573  }
1574  return 0;
1575 }
1576 
1577 int
1578 SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect * rect)
1579 {
1580  SDL_Rect full_rect = { 0, 0, 0, 0 };
1581 
1582  CHECK_RENDERER_MAGIC(renderer, -1);
1583 
1584  /* If 'rect' == NULL, then outline the whole surface */
1585  if (!rect) {
1586  SDL_RenderGetViewport(renderer, &full_rect);
1587  full_rect.x = 0;
1588  full_rect.y = 0;
1589  rect = &full_rect;
1590  }
1591  return SDL_RenderFillRects(renderer, rect, 1);
1592 }
1593 
1594 int
1596  const SDL_Rect * rects, int count)
1597 {
1598  SDL_FRect *frects;
1599  int i;
1600  int status;
1601 
1602  CHECK_RENDERER_MAGIC(renderer, -1);
1603 
1604  if (!rects) {
1605  return SDL_SetError("SDL_RenderFillRects(): Passed NULL rects");
1606  }
1607  if (count < 1) {
1608  return 0;
1609  }
1610  /* Don't draw while we're hidden */
1611  if (renderer->hidden) {
1612  return 0;
1613  }
1614 
1615  frects = SDL_stack_alloc(SDL_FRect, count);
1616  if (!frects) {
1617  return SDL_OutOfMemory();
1618  }
1619  for (i = 0; i < count; ++i) {
1620  frects[i].x = rects[i].x * renderer->scale.x;
1621  frects[i].y = rects[i].y * renderer->scale.y;
1622  frects[i].w = rects[i].w * renderer->scale.x;
1623  frects[i].h = rects[i].h * renderer->scale.y;
1624  }
1625 
1626  status = renderer->RenderFillRects(renderer, frects, count);
1627 
1628  SDL_stack_free(frects);
1629 
1630  return status;
1631 }
1632 
1633 int
1635  const SDL_Rect * srcrect, const SDL_Rect * dstrect)
1636 {
1637  SDL_Rect real_srcrect = { 0, 0, 0, 0 };
1638  SDL_Rect real_dstrect = { 0, 0, 0, 0 };
1639  SDL_FRect frect;
1640 
1641  CHECK_RENDERER_MAGIC(renderer, -1);
1642  CHECK_TEXTURE_MAGIC(texture, -1);
1643 
1644  if (renderer != texture->renderer) {
1645  return SDL_SetError("Texture was not created with this renderer");
1646  }
1647 
1648  real_srcrect.x = 0;
1649  real_srcrect.y = 0;
1650  real_srcrect.w = texture->w;
1651  real_srcrect.h = texture->h;
1652  if (srcrect) {
1653  if (!SDL_IntersectRect(srcrect, &real_srcrect, &real_srcrect)) {
1654  return 0;
1655  }
1656  }
1657 
1658  SDL_RenderGetViewport(renderer, &real_dstrect);
1659  real_dstrect.x = 0;
1660  real_dstrect.y = 0;
1661  if (dstrect) {
1662  if (!SDL_HasIntersection(dstrect, &real_dstrect)) {
1663  return 0;
1664  }
1665  real_dstrect = *dstrect;
1666  }
1667 
1668  if (texture->native) {
1669  texture = texture->native;
1670  }
1671 
1672  /* Don't draw while we're hidden */
1673  if (renderer->hidden) {
1674  return 0;
1675  }
1676 
1677  frect.x = real_dstrect.x * renderer->scale.x;
1678  frect.y = real_dstrect.y * renderer->scale.y;
1679  frect.w = real_dstrect.w * renderer->scale.x;
1680  frect.h = real_dstrect.h * renderer->scale.y;
1681 
1682  return renderer->RenderCopy(renderer, texture, &real_srcrect, &frect);
1683 }
1684 
1685 
1686 int
1688  const SDL_Rect * srcrect, const SDL_Rect * dstrect,
1689  const double angle, const SDL_Point *center, const SDL_RendererFlip flip)
1690 {
1691  SDL_Rect real_srcrect = { 0, 0, 0, 0 };
1692  SDL_Rect real_dstrect = { 0, 0, 0, 0 };
1693  SDL_Point real_center;
1694  SDL_FRect frect;
1695  SDL_FPoint fcenter;
1696 
1697  CHECK_RENDERER_MAGIC(renderer, -1);
1698  CHECK_TEXTURE_MAGIC(texture, -1);
1699 
1700  if (renderer != texture->renderer) {
1701  return SDL_SetError("Texture was not created with this renderer");
1702  }
1703  if (!renderer->RenderCopyEx) {
1704  return SDL_SetError("Renderer does not support RenderCopyEx");
1705  }
1706 
1707  real_srcrect.x = 0;
1708  real_srcrect.y = 0;
1709  real_srcrect.w = texture->w;
1710  real_srcrect.h = texture->h;
1711  if (srcrect) {
1712  if (!SDL_IntersectRect(srcrect, &real_srcrect, &real_srcrect)) {
1713  return 0;
1714  }
1715  }
1716 
1717  /* We don't intersect the dstrect with the viewport as RenderCopy does because of potential rotation clipping issues... TODO: should we? */
1718  if (dstrect) {
1719  real_dstrect = *dstrect;
1720  } else {
1721  SDL_RenderGetViewport(renderer, &real_dstrect);
1722  real_dstrect.x = 0;
1723  real_dstrect.y = 0;
1724  }
1725 
1726  if (texture->native) {
1727  texture = texture->native;
1728  }
1729 
1730  if(center) real_center = *center;
1731  else {
1732  real_center.x = real_dstrect.w/2;
1733  real_center.y = real_dstrect.h/2;
1734  }
1735 
1736  frect.x = real_dstrect.x * renderer->scale.x;
1737  frect.y = real_dstrect.y * renderer->scale.y;
1738  frect.w = real_dstrect.w * renderer->scale.x;
1739  frect.h = real_dstrect.h * renderer->scale.y;
1740 
1741  fcenter.x = real_center.x * renderer->scale.x;
1742  fcenter.y = real_center.y * renderer->scale.y;
1743 
1744  return renderer->RenderCopyEx(renderer, texture, &real_srcrect, &frect, angle, &fcenter, flip);
1745 }
1746 
1747 int
1748 SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
1749  Uint32 format, void * pixels, int pitch)
1750 {
1751  SDL_Rect real_rect;
1752 
1753  CHECK_RENDERER_MAGIC(renderer, -1);
1754 
1755  if (!renderer->RenderReadPixels) {
1756  return SDL_Unsupported();
1757  }
1758 
1759  if (!format) {
1760  format = SDL_GetWindowPixelFormat(renderer->window);
1761  }
1762 
1763  real_rect.x = renderer->viewport.x;
1764  real_rect.y = renderer->viewport.y;
1765  real_rect.w = renderer->viewport.w;
1766  real_rect.h = renderer->viewport.h;
1767  if (rect) {
1768  if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
1769  return 0;
1770  }
1771  if (real_rect.y > rect->y) {
1772  pixels = (Uint8 *)pixels + pitch * (real_rect.y - rect->y);
1773  }
1774  if (real_rect.x > rect->x) {
1775  int bpp = SDL_BYTESPERPIXEL(format);
1776  pixels = (Uint8 *)pixels + bpp * (real_rect.x - rect->x);
1777  }
1778  }
1779 
1780  return renderer->RenderReadPixels(renderer, &real_rect,
1781  format, pixels, pitch);
1782 }
1783 
1784 void
1786 {
1787  CHECK_RENDERER_MAGIC(renderer, );
1788 
1789  /* Don't draw while we're hidden */
1790  if (renderer->hidden) {
1791  return;
1792  }
1793  renderer->RenderPresent(renderer);
1794 }
1795 
1796 void
1798 {
1799  SDL_Renderer *renderer;
1800 
1801  CHECK_TEXTURE_MAGIC(texture, );
1802 
1803  renderer = texture->renderer;
1804  if (texture == renderer->target) {
1805  SDL_SetRenderTarget(renderer, NULL);
1806  }
1807 
1808  texture->magic = NULL;
1809 
1810  if (texture->next) {
1811  texture->next->prev = texture->prev;
1812  }
1813  if (texture->prev) {
1814  texture->prev->next = texture->next;
1815  } else {
1816  renderer->textures = texture->next;
1817  }
1818 
1819  if (texture->native) {
1820  SDL_DestroyTexture(texture->native);
1821  }
1822  if (texture->yuv) {
1823  SDL_SW_DestroyYUVTexture(texture->yuv);
1824  }
1825  SDL_free(texture->pixels);
1826 
1827  renderer->DestroyTexture(renderer, texture);
1828  SDL_free(texture);
1829 }
1830 
1831 void
1833 {
1834  CHECK_RENDERER_MAGIC(renderer, );
1835 
1837 
1838  /* Free existing textures for this renderer */
1839  while (renderer->textures) {
1840  SDL_DestroyTexture(renderer->textures);
1841  }
1842 
1843  if (renderer->window) {
1845  }
1846 
1847  /* It's no longer magical... */
1848  renderer->magic = NULL;
1849 
1850  /* Free the renderer instance */
1851  renderer->DestroyRenderer(renderer);
1852 }
1853 
1854 int SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh)
1855 {
1856  SDL_Renderer *renderer;
1857 
1858  CHECK_TEXTURE_MAGIC(texture, -1);
1859  renderer = texture->renderer;
1860  if (texture->native) {
1861  return SDL_GL_BindTexture(texture->native, texw, texh);
1862  } else if (renderer && renderer->GL_BindTexture) {
1863  return renderer->GL_BindTexture(renderer, texture, texw, texh);
1864  } else {
1865  return SDL_Unsupported();
1866  }
1867 }
1868 
1870 {
1871  SDL_Renderer *renderer;
1872 
1873  CHECK_TEXTURE_MAGIC(texture, -1);
1874  renderer = texture->renderer;
1875  if (renderer && renderer->GL_UnbindTexture) {
1876  return renderer->GL_UnbindTexture(renderer, texture);
1877  }
1878 
1879  return SDL_Unsupported();
1880 }
1881 
1882 /* vi: set ts=4 sw=4 expandtab: */
DECLSPEC int SDLCALL SDL_SetRenderDrawBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode)
Set the blend mode used for drawing operations (Fill and Line).
Definition: SDL_render.c:1306
void * pixels
Definition: SDL_sysrender.h:65
int(* UpdateClipRect)(SDL_Renderer *renderer)
SDL_BlendMode blendMode
Definition: SDL_sysrender.h:57
SDL_MouseMotionEvent motion
Definition: SDL_events.h:503
DECLSPEC void SDLCALL SDL_RenderGetClipRect(SDL_Renderer *renderer, SDL_Rect *rect)
Get the clip rectangle for the current target.
Definition: SDL_render.c:1236
DECLSPEC int SDL_GetRenderDrawColor(SDL_Renderer *renderer, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
Get the color used for drawing operations (Rect, Line and Clear).
Definition: SDL_render.c:1285
DECLSPEC int SDLCALL SDL_RenderSetViewport(SDL_Renderer *renderer, const SDL_Rect *rect)
Set the drawing area for rendering on the current target.
Definition: SDL_render.c:1187
DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface *surface)
Definition: SDL_surface.c:1053
DECLSPEC SDL_Texture *SDLCALL SDL_GetRenderTarget(SDL_Renderer *renderer)
Get the current render target or NULL for the default render target.
Definition: SDL_render.c:1101
DECLSPEC int SDLCALL SDL_GL_UnbindTexture(SDL_Texture *texture)
Unbind a texture from the current OpenGL/ES/ES2 context.
Definition: SDL_render.c:1869
DECLSPEC int SDLCALL SDL_SetTextureColorMod(SDL_Texture *texture, Uint8 r, Uint8 g, Uint8 b)
Set an additional color value used in render copy operations.
Definition: SDL_render.c:586
DECLSPEC int SDL_SetRenderDrawColor(SDL_Renderer *renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Set the color used for drawing operations (Rect, Line and Clear).
Definition: SDL_render.c:1272
SDL_SW_YUVTexture * SDL_SW_CreateYUVTexture(Uint32 format, int w, int h)
Definition: SDL_yuv_sw.c:1021
static Uint32 GetClosestSupportedFormat(SDL_Renderer *renderer, Uint32 format)
Definition: SDL_render.c:370
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:7294
static int SDL_UpdateTextureYUVPlanar(SDL_Texture *texture, const SDL_Rect *rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch)
Definition: SDL_render.c:809
DECLSPEC double SDLCALL SDL_fabs(double x)
Definition: SDL_stdlib.c:90
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Definition: SDL_sysrender.h:80
DECLSPEC void SDLCALL SDL_FreeFormat(SDL_PixelFormat *format)
Free an SDL_PixelFormat structure.
Definition: SDL_pixels.c:584
#define SDL_HINT_RENDER_VSYNC
A variable controlling whether updates to the SDL screen surface should be synchronized with the vert...
Definition: SDL_hints.h:129
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:40
SDL_RendererInfo info
DECLSPEC int SDLCALL SDL_GetTextureAlphaMod(SDL_Texture *texture, Uint8 *alpha)
Get the additional alpha value used in render copy operations.
Definition: SDL_render.c:652
DECLSPEC int SDLCALL SDL_RenderSetScale(SDL_Renderer *renderer, float scaleX, float scaleY)
Set the drawing scale for rendering on the current target.
Definition: SDL_render.c:1249
DECLSPEC int SDLCALL SDL_ConvertPixels(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Copy a block of pixels of one format to another format.
Definition: SDL_surface.c:984
GLboolean GLboolean g
Definition: glew.h:8736
SDL_Rect clip_rect_backup
#define NULL
Definition: ftobjs.h:61
int(* RenderClear)(SDL_Renderer *renderer)
GLclampf f
Definition: glew.h:3390
#define SDL_ISPIXELFORMAT_INDEXED(format)
Definition: SDL_pixels.h:129
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:227
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
DECLSPEC int SDLCALL SDL_CreateWindowAndRenderer(int width, int height, Uint32 window_flags, SDL_Window **window, SDL_Renderer **renderer)
Create a window and default renderer.
Definition: SDL_render.c:184
GLdouble angle
Definition: glew.h:8396
SDL_bool
Definition: SDL_stdinc.h:116
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:82
GLclampd n
Definition: glew.h:7287
SDL_Renderer *(* CreateRenderer)(SDL_Window *window, Uint32 flags)
DECLSPEC void SDLCALL SDL_DestroyTexture(SDL_Texture *texture)
Destroy the specified texture.
Definition: SDL_render.c:1797
SDL_bool hidden
DECLSPEC int SDLCALL SDL_RenderDrawRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count)
Draw some number of rectangles on the current rendering target.
Definition: SDL_render.c:1551
DECLSPEC int SDLCALL SDL_RenderDrawLine(SDL_Renderer *renderer, int x1, int y1, int x2, int y2)
Draw a line on the current rendering target.
Definition: SDL_render.c:1413
EGLSurface EGLint x
Definition: eglext.h:293
EGLSurface surface
Definition: eglext.h:74
The structure that defines a point.
Definition: SDL_rect.h:47
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
DECLSPEC int SDLCALL SDL_GetTextureColorMod(SDL_Texture *texture, Uint8 *r, Uint8 *g, Uint8 *b)
Get the additional color value used in render copy operations.
Definition: SDL_render.c:611
DECLSPEC void SDLCALL SDL_free(void *mem)
SDL_FPoint scale
Uint32 texture_formats[16]
Definition: SDL_render.h:83
int SDL_SW_LockYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_yuv_sw.c:1242
EGLSurface EGLint EGLint EGLint EGLint height
Definition: eglext.h:293
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:8736
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:123
SDL_Rect locked_rect
Definition: SDL_sysrender.h:67
DECLSPEC void SDLCALL SDL_GetWindowSize(SDL_Window *window, int *w, int *h)
Get the size of a window&#39;s client area.
Definition: SDL_video.c:1638
DECLSPEC void SDLCALL SDL_RenderGetScale(SDL_Renderer *renderer, float *scaleX, float *scaleY)
Get the drawing scale for the current target.
Definition: SDL_render.c:1259
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:99
static int SDL_UpdateTextureNative(SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_render.c:738
#define SDL_WINDOWPOS_UNDEFINED
Definition: SDL_video.h:119
#define SDL_ISPIXELFORMAT_ALPHA(format)
Definition: SDL_pixels.h:135
DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer *renderer, int *w, int *h)
Get the output size of a rendering context.
Definition: SDL_render.c:338
DECLSPEC int SDLCALL SDL_RenderSetLogicalSize(SDL_Renderer *renderer, int w, int h)
Set device independent resolution for rendering.
Definition: SDL_render.c:1154
SDL_Rect clip_rect
static int RenderDrawPointsWithRects(SDL_Renderer *renderer, const SDL_Point *points, int count)
Definition: SDL_render.c:1346
DECLSPEC int SDLCALL SDL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
Read pixels from the current rendering target.
Definition: SDL_render.c:1748
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
DECLSPEC int SDLCALL SDL_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count)
Draw multiple points on the current rendering target.
Definition: SDL_render.c:1372
const char * name
Definition: SDL_render.h:80
DECLSPEC int SDLCALL SDL_GetColorKey(SDL_Surface *surface, Uint32 *key)
Gets the color key (transparent pixel) in a blittable surface.
Definition: SDL_surface.c:218
GLuint GLfloat GLfloat GLfloat GLfloat y1
Definition: glew.h:11582
SDL_Texture * textures
DECLSPEC SDL_Renderer *SDLCALL SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags)
Create a 2D rendering context for a window.
Definition: SDL_render.c:204
GLfixed GLfixed GLfixed y2
Definition: glext.h:4559
static char texture_magic
Definition: SDL_render.c:73
SDL_Window * window
DECLSPEC int SDLCALL SDL_RenderDrawPoint(SDL_Renderer *renderer, int x, int y)
Draw a point on the current rendering target.
Definition: SDL_render.c:1336
SDL_RendererInfo info
static int SDL_LockTextureYUV(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_render.c:913
static int RenderDrawLinesWithRects(SDL_Renderer *renderer, const SDL_Point *points, int count)
Definition: SDL_render.c:1425
DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_Texture *texture)
Unlock a texture, uploading the changes to video memory, if needed.
Definition: SDL_render.c:1005
SDL_Renderer * SW_CreateRendererForSurface(SDL_Surface *surface)
DECLSPEC int SDLCALL SDL_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_Rect *dstrect)
Copy a portion of the texture to the current rendering target.
Definition: SDL_render.c:1634
SDL_FPoint scale_backup
DECLSPEC int SDLCALL SDL_GetRenderDrawBlendMode(SDL_Renderer *renderer, SDL_BlendMode *blendMode)
Get the blend mode used for drawing operations.
Definition: SDL_render.c:1315
DECLSPEC int SDLCALL SDL_SetTextureBlendMode(SDL_Texture *texture, SDL_BlendMode blendMode)
Set the blend mode used for texture copy operations.
Definition: SDL_render.c:663
static void SDL_UnlockTextureNative(SDL_Texture *texture)
Definition: SDL_render.c:984
SDL_WindowEvent window
Definition: SDL_events.h:499
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window *window)
Get the pixel format associated with the window.
Definition: SDL_video.c:1059
int SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_yuv_sw.c:1114
int x
Definition: SDL_rect.h:49
DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface *surface)
Definition: SDL_surface.c:786
DECLSPEC int SDLCALL SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
Set a texture as the current rendering target.
Definition: SDL_render.c:1034
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_sysrender.h:97
SDL_Texture * next
Definition: SDL_sysrender.h:72
DECLSPEC int SDLCALL SDL_QueryTexture(SDL_Texture *texture, Uint32 *format, int *access, int *w, int *h)
Query the attributes of a texture.
Definition: SDL_render.c:565
#define CHECK_RENDERER_MAGIC(renderer, retval)
Definition: SDL_render.c:35
int(* UpdateTextureYUV)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch)
Definition: SDL_sysrender.h:92
DECLSPEC SDL_PixelFormat *SDLCALL SDL_AllocFormat(Uint32 pixel_format)
Create an SDL_PixelFormat structure from a pixel format enum.
Definition: SDL_pixels.c:486
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_sysrender.h:89
SDL_Texture * prev
Definition: SDL_sysrender.h:71
DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *result)
Calculate the intersection of two rectangles.
Definition: SDL_rect.c:75
SDL_RenderDriver SW_RenderDriver
Definition: SDL_render_sw.c:78
int
Definition: SDL_systhread.c:37
SDL_Texture * target
DECLSPEC SDL_Renderer *SDLCALL SDL_GetRenderer(SDL_Window *window)
Get the renderer associated with a window.
Definition: SDL_render.c:323
int y
Definition: SDL_rect.h:50
void * pixels
Definition: SDL_surface.h:75
EGLSurface EGLint EGLint EGLint width
Definition: eglext.h:293
DECLSPEC int SDLCALL SDL_GetSurfaceColorMod(SDL_Surface *surface, Uint8 *r, Uint8 *g, Uint8 *b)
Get the additional color value used in blit operations.
Definition: SDL_surface.c:332
SDL_SW_YUVTexture * yuv
Definition: SDL_sysrender.h:64
SDL_BlendMode blendMode
DECLSPEC SDL_Renderer *SDLCALL SDL_CreateSoftwareRenderer(SDL_Surface *surface)
Create a 2D software rendering context for a surface.
Definition: SDL_render.c:301
GLint GLsizei count
Definition: gl2ext.h:1011
DECLSPEC SDL_bool SDLCALL SDL_HasIntersection(const SDL_Rect *A, const SDL_Rect *B)
Determine whether two rectangles intersect.
Definition: SDL_rect.c:28
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
#define SDL_max(x, y)
Definition: SDL_stdinc.h:245
DECLSPEC SDL_Window *SDLCALL SDL_GetWindowFromID(Uint32 id)
Get a window from a stored ID, or NULL if it doesn&#39;t exist.
Definition: SDL_video.c:1393
DECLSPEC void *SDLCALL SDL_SetWindowData(SDL_Window *window, const char *name, void *userdata)
Associate an arbitrary named pointer with a window.
Definition: SDL_video.c:1467
DECLSPEC void SDLCALL SDL_RenderGetLogicalSize(SDL_Renderer *renderer, int *w, int *h)
Get device independent resolution for rendering.
Definition: SDL_render.c:1174
DECLSPEC SDL_Texture *SDLCALL SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *surface)
Create a texture from an existing surface.
Definition: SDL_render.c:481
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
int(* SetTextureColorMod)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:83
DECLSPEC void *SDLCALL SDL_GetWindowData(SDL_Window *window, const char *name)
Retrieve the data pointer associated with a window.
Definition: SDL_video.c:1514
GLuint index
Definition: glew.h:1800
DECLSPEC Uint32 SDLCALL SDL_GetWindowFlags(SDL_Window *window)
Get the window flags.
Definition: SDL_video.c:1409
void SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture *swdata)
Definition: SDL_yuv_sw.c:1387
int x
Definition: SDL_rect.h:65
GLclampf GLclampf GLclampf alpha
Definition: glew.h:1506
DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurface(SDL_Surface *src, const SDL_PixelFormat *fmt, Uint32 flags)
Definition: SDL_surface.c:804
DECLSPEC const char *SDLCALL SDL_GetHint(const char *name)
Get a hint.
Definition: SDL_hints.c:104
DECLSPEC double SDLCALL SDL_floor(double x)
Definition: SDL_stdlib.c:100
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int w
Definition: SDL_rect.h:66
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
GLenum GLenum GLenum GLenum GLenum scale
Definition: glew.h:12632
static int UpdateLogicalSize(SDL_Renderer *renderer)
Definition: SDL_render.c:1107
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:111
static int SDL_UpdateTextureYUV(SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_render.c:692
DECLSPEC void SDLCALL SDL_AddEventWatch(SDL_EventFilter filter, void *userdata)
Definition: SDL_events.c:504
GLuint GLfloat GLfloat GLfloat x1
Definition: glew.h:11582
#define SDL_assert(condition)
Definition: SDL_assert.h:159
int(* SetTextureBlendMode)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:87
DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer *renderer)
Clear the current rendering target with the drawing color.
Definition: SDL_render.c:1324
EGLSurface EGLint EGLint y
Definition: eglext.h:293
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
DECLSPEC SDL_bool SDLCALL SDL_RenderTargetSupported(SDL_Renderer *renderer)
Determines whether a window supports the use of render targets.
Definition: SDL_render.c:1025
GLenum GLenum GLuint texture
Definition: gl2ext.h:850
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:83
DECLSPEC void SDLCALL SDL_RenderGetViewport(SDL_Renderer *renderer, SDL_Rect *rect)
Get the drawing area for the current target.
Definition: SDL_render.c:1207
SDL_PixelFormat * format
Definition: SDL_surface.h:72
DECLSPEC int SDLCALL SDL_RenderDrawRect(SDL_Renderer *renderer, const SDL_Rect *rect)
Draw a rectangle on the current rendering target.
Definition: SDL_render.c:1522
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
Definition: SDL_sysrender.h:81
DECLSPEC int SDLCALL SDL_SetTextureAlphaMod(SDL_Texture *texture, Uint8 alpha)
Set an additional alpha value used in render copy operations.
Definition: SDL_render.c:629
DECLSPEC SDL_Window *SDLCALL SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
Create a window with the specified position, dimensions, and flags.
Definition: SDL_video.c:1190
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl2ext.h:845
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
Information on the capabilities of a render driver or context.
Definition: SDL_render.h:78
static const SDL_RenderDriver * render_drivers[]
Definition: SDL_render.c:49
#define SDL_WINDOWRENDERDATA
Definition: SDL_render.c:33
static SDL_bool IsSupportedFormat(SDL_Renderer *renderer, Uint32 format)
Definition: SDL_render.c:357
DECLSPEC int SDLCALL SDL_GetTextureBlendMode(SDL_Texture *texture, SDL_BlendMode *blendMode)
Get the blend mode used for texture copy operations.
Definition: SDL_render.c:681
DECLSPEC void SDLCALL SDL_DelEventWatch(SDL_EventFilter filter, void *userdata)
Definition: SDL_events.c:521
SDL_Renderer * renderer
Definition: SDL_sysrender.h:60
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
GLenum access
Definition: glew.h:3469
DECLSPEC int SDLCALL SDL_GetRendererInfo(SDL_Renderer *renderer, SDL_RendererInfo *info)
Get information about a rendering context.
Definition: SDL_render.c:329
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2767
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
#define CHECK_TEXTURE_MAGIC(texture, retval)
Definition: SDL_render.c:41
int SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch)
Definition: SDL_yuv_sw.c:1188
#define SDL_MUSTLOCK(S)
Definition: SDL_surface.h:61
SDL_Rect viewport
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
int h
Definition: SDL_rect.h:66
DECLSPEC int SDLCALL SDL_LockTexture(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Lock a portion of the texture for write-only pixel access.
Definition: SDL_render.c:932
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
DECLSPEC int SDLCALL SDL_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count)
Fill some number of rectangles on the current rendering target with the drawing color.
Definition: SDL_render.c:1595
DECLSPEC int SDLCALL SDL_RenderSetClipRect(SDL_Renderer *renderer, const SDL_Rect *rect)
Set the clip rectangle for the current target.
Definition: SDL_render.c:1220
GLfixed GLfixed x2
Definition: glext.h:4559
int SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture *swdata, const SDL_Rect *srcrect, Uint32 target_format, int w, int h, void *pixels, int pitch)
Definition: SDL_yuv_sw.c:1272
#define SDL_HINT_RENDER_DRIVER
A variable specifying which render driver to use.
Definition: SDL_hints.h:84
DECLSPEC double SDLCALL SDL_ceil(double x)
Definition: SDL_stdlib.c:50
SDL_MouseButtonEvent button
Definition: SDL_events.h:504
GLdouble GLdouble GLdouble r
Definition: glew.h:1392
const void * magic
Definition: SDL_sysrender.h:78
GLdouble GLdouble GLdouble b
Definition: glew.h:8383
Uint32 num_texture_formats
Definition: SDL_render.h:82
Uint32 format
Definition: SDL_sysrender.h:52
GLint GLint GLint GLint GLint w
Definition: gl2ext.h:1215
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:226
static char renderer_magic
Definition: SDL_render.c:72
General event structure.
Definition: SDL_events.h:495
DECLSPEC int SDLCALL SDL_GetNumRenderDrivers(void)
Get the number of 2D rendering drivers available for the current display.
Definition: SDL_render.c:78
int(* UpdateViewport)(SDL_Renderer *renderer)
DECLSPEC int SDLCALL SDL_UpdateYUVTexture(SDL_Texture *texture, const SDL_Rect *rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch)
Update a rectangle within a planar YV12 or IYUV texture with new pixel data.
Definition: SDL_render.c:856
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glew.h:3337
DECLSPEC SDL_Texture *SDLCALL SDL_CreateTexture(SDL_Renderer *renderer, Uint32 format, int access, int w, int h)
Create a texture for a rendering context.
Definition: SDL_render.c:396
DECLSPEC int SDLCALL SDL_GetSurfaceAlphaMod(SDL_Surface *surface, Uint8 *alpha)
Get the additional alpha value used in blit operations.
Definition: SDL_surface.c:374
DECLSPEC int SDLCALL SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh)
Bind the texture to the current OpenGL/ES/ES2 context for use with OpenGL instructions.
Definition: SDL_render.c:1854
DECLSPEC int SDLCALL SDL_RenderFillRect(SDL_Renderer *renderer, const SDL_Rect *rect)
Fill a rectangle on the current rendering target with the drawing color.
Definition: SDL_render.c:1578
#define SDL_zero(x)
Definition: SDL_stdinc.h:254
SDL_Texture * native
Definition: SDL_sysrender.h:63
#define SDL_ISPIXELFORMAT_FOURCC(format)
Definition: SDL_pixels.h:143
#define SDL_min(x, y)
Definition: SDL_stdinc.h:244
int i
Definition: pngrutil.c:1377
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)
SDL_Rect viewport_backup
DECLSPEC int SDLCALL SDL_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count)
Draw a series of connected lines on the current rendering target.
Definition: SDL_render.c:1481
void(* RenderPresent)(SDL_Renderer *renderer)
void(* DestroyRenderer)(SDL_Renderer *renderer)
const void * magic
Definition: SDL_sysrender.h:51
DECLSPEC void SDLCALL SDL_LogInfo(int category, const char *fmt,...)
Log a message with SDL_LOG_PRIORITY_INFO.
Definition: SDL_log.c:203
int(* SetTextureAlphaMod)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:85
DECLSPEC int SDLCALL SDL_GetRenderDriverInfo(int index, SDL_RendererInfo *info)
Get information about a specific 2D rendering driver for the current display.
Definition: SDL_render.c:88
static void SDL_UnlockTextureYUV(SDL_Texture *texture)
Definition: SDL_render.c:963
DECLSPEC int SDLCALL SDL_LockSurface(SDL_Surface *surface)
Sets up a surface for directly accessing the pixels.
Definition: SDL_surface.c:765
int y
Definition: SDL_rect.h:65
#define SDL_Unsupported()
Definition: SDL_error.h:53
DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2)
Definition: SDL_string.c:946
static int SDL_RendererEventWatch(void *userdata, SDL_Event *event)
Definition: SDL_render.c:103
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
static int SDL_LockTextureNative(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_render.c:920
Uint32 type
Definition: SDL_events.h:497
DECLSPEC void SDLCALL SDL_DestroyRenderer(SDL_Renderer *renderer)
Destroy the rendering context for a window and free associated textures.
Definition: SDL_render.c:1832
cl_event event
Definition: glew.h:3556
DECLSPEC void SDLCALL SDL_RenderPresent(SDL_Renderer *renderer)
Update the screen with rendering performed.
Definition: SDL_render.c:1785
DECLSPEC int SDLCALL SDL_GetSurfaceBlendMode(SDL_Surface *surface, SDL_BlendMode *blendMode)
Get the blend mode used for blit operations.
Definition: SDL_surface.c:424
DECLSPEC int SDLCALL SDL_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_Rect *dstrect, const double angle, const SDL_Point *center, const SDL_RendererFlip flip)
Copy a portion of the source texture to the current rendering target, rotating it by angle around the...
Definition: SDL_render.c:1687
DECLSPEC int SDLCALL SDL_UpdateTexture(SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Update the given texture rectangle with new pixel data.
Definition: SDL_render.c:775