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