SDL  2.0
SDL_render.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../SDL_internal.h"
22 
23 /* 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  SDL_assert(renderer && renderer->magic == &renderer_magic); \
37  if (!renderer || renderer->magic != &renderer_magic) { \
38  SDL_SetError("Invalid renderer"); \
39  return retval; \
40  }
41 
42 #define CHECK_TEXTURE_MAGIC(texture, retval) \
43  SDL_assert(texture && texture->magic == &texture_magic); \
44  if (!texture || texture->magic != &texture_magic) { \
45  SDL_SetError("Invalid texture"); \
46  return retval; \
47  }
48 
49 /* Predefined blend modes */
50 #define SDL_COMPOSE_BLENDMODE(srcColorFactor, dstColorFactor, colorOperation, \
51  srcAlphaFactor, dstAlphaFactor, alphaOperation) \
52  (SDL_BlendMode)(((Uint32)colorOperation << 0) | \
53  ((Uint32)srcColorFactor << 4) | \
54  ((Uint32)dstColorFactor << 8) | \
55  ((Uint32)alphaOperation << 16) | \
56  ((Uint32)srcAlphaFactor << 20) | \
57  ((Uint32)dstAlphaFactor << 24))
58 
59 #define SDL_BLENDMODE_NONE_FULL \
60  SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ZERO, SDL_BLENDOPERATION_ADD, \
61  SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ZERO, SDL_BLENDOPERATION_ADD)
62 
63 #define SDL_BLENDMODE_BLEND_FULL \
64  SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, \
65  SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD)
66 
67 #define SDL_BLENDMODE_ADD_FULL \
68  SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD, \
69  SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD)
70 
71 #define SDL_BLENDMODE_MOD_FULL \
72  SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_SRC_COLOR, SDL_BLENDOPERATION_ADD, \
73  SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD)
74 
75 #if !SDL_RENDER_DISABLED
76 static const SDL_RenderDriver *render_drivers[] = {
77 #if SDL_VIDEO_RENDER_D3D
79 #endif
80 #if SDL_VIDEO_RENDER_D3D11
82 #endif
83 #if SDL_VIDEO_RENDER_OGL
85 #endif
86 #if SDL_VIDEO_RENDER_OGL_ES2
88 #endif
89 #if SDL_VIDEO_RENDER_OGL_ES
91 #endif
92 #if SDL_VIDEO_RENDER_DIRECTFB
94 #endif
95 #if SDL_VIDEO_RENDER_METAL
97 #endif
98 #if SDL_VIDEO_RENDER_PSP
100 #endif
102 };
103 #endif /* !SDL_RENDER_DISABLED */
104 
105 static char renderer_magic;
106 static char texture_magic;
107 
109 
110 int
112 {
113 #if !SDL_RENDER_DISABLED
114  return SDL_arraysize(render_drivers);
115 #else
116  return 0;
117 #endif
118 }
119 
120 int
122 {
123 #if !SDL_RENDER_DISABLED
125  return SDL_SetError("index must be in the range of 0 - %d",
127  }
128  *info = render_drivers[index]->info;
129  return 0;
130 #else
131  return SDL_SetError("SDL not built with rendering support");
132 #endif
133 }
134 
135 static int SDLCALL
137 {
138  SDL_Renderer *renderer = (SDL_Renderer *)userdata;
139 
140  if (event->type == SDL_WINDOWEVENT) {
142  if (window == renderer->window) {
143  if (renderer->WindowEvent) {
144  renderer->WindowEvent(renderer, &event->window);
145  }
146 
147  if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
148  /* Make sure we're operating on the default render target */
149  SDL_Texture *saved_target = SDL_GetRenderTarget(renderer);
150  if (saved_target) {
151  SDL_SetRenderTarget(renderer, NULL);
152  }
153 
154  if (renderer->logical_w) {
155  UpdateLogicalSize(renderer);
156  } else {
157  /* Window was resized, reset viewport */
158  int w, h;
159 
160  if (renderer->GetOutputSize) {
161  renderer->GetOutputSize(renderer, &w, &h);
162  } else {
163  SDL_GetWindowSize(renderer->window, &w, &h);
164  }
165 
166  if (renderer->target) {
167  renderer->viewport_backup.x = 0;
168  renderer->viewport_backup.y = 0;
169  renderer->viewport_backup.w = w;
170  renderer->viewport_backup.h = h;
171  } else {
172  renderer->viewport.x = 0;
173  renderer->viewport.y = 0;
174  renderer->viewport.w = w;
175  renderer->viewport.h = h;
176  renderer->UpdateViewport(renderer);
177  }
178  }
179 
180  if (saved_target) {
181  SDL_SetRenderTarget(renderer, saved_target);
182  }
183  } else if (event->window.event == SDL_WINDOWEVENT_HIDDEN) {
184  renderer->hidden = SDL_TRUE;
185  } else if (event->window.event == SDL_WINDOWEVENT_SHOWN) {
186  if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)) {
187  renderer->hidden = SDL_FALSE;
188  }
189  } else if (event->window.event == SDL_WINDOWEVENT_MINIMIZED) {
190  renderer->hidden = SDL_TRUE;
191  } else if (event->window.event == SDL_WINDOWEVENT_RESTORED ||
193  if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_HIDDEN)) {
194  renderer->hidden = SDL_FALSE;
195  }
196  }
197  }
198  } else if (event->type == SDL_MOUSEMOTION) {
200  if (renderer->logical_w && window == renderer->window) {
201  event->motion.x -= (int)(renderer->viewport.x * renderer->dpi_scale.x);
202  event->motion.y -= (int)(renderer->viewport.y * renderer->dpi_scale.y);
203  event->motion.x = (int)(event->motion.x / (renderer->scale.x * renderer->dpi_scale.x));
204  event->motion.y = (int)(event->motion.y / (renderer->scale.y * renderer->dpi_scale.y));
205  if (event->motion.xrel > 0) {
206  event->motion.xrel = SDL_max(1, (int)(event->motion.xrel / (renderer->scale.x * renderer->dpi_scale.x)));
207  } else if (event->motion.xrel < 0) {
208  event->motion.xrel = SDL_min(-1, (int)(event->motion.xrel / (renderer->scale.x * renderer->dpi_scale.x)));
209  }
210  if (event->motion.yrel > 0) {
211  event->motion.yrel = SDL_max(1, (int)(event->motion.yrel / (renderer->scale.y * renderer->dpi_scale.y)));
212  } else if (event->motion.yrel < 0) {
213  event->motion.yrel = SDL_min(-1, (int)(event->motion.yrel / (renderer->scale.y * renderer->dpi_scale.y)));
214  }
215  }
216  } else if (event->type == SDL_MOUSEBUTTONDOWN ||
217  event->type == SDL_MOUSEBUTTONUP) {
219  if (renderer->logical_w && window == renderer->window) {
220  event->button.x -= (int)(renderer->viewport.x * renderer->dpi_scale.x);
221  event->button.y -= (int)(renderer->viewport.y * renderer->dpi_scale.y);
222  event->button.x = (int)(event->button.x / (renderer->scale.x * renderer->dpi_scale.x));
223  event->button.y = (int)(event->button.y / (renderer->scale.y * renderer->dpi_scale.y));
224  }
225  } else if (event->type == SDL_FINGERDOWN ||
226  event->type == SDL_FINGERUP ||
227  event->type == SDL_FINGERMOTION) {
228  if (renderer->logical_w) {
229  int w = 1;
230  int h = 1;
231  SDL_GetRendererOutputSize(renderer, &w, &h);
232 
233  event->tfinger.x *= (w - 1);
234  event->tfinger.y *= (h - 1);
235 
236  event->tfinger.x -= (renderer->viewport.x * renderer->dpi_scale.x);
237  event->tfinger.y -= (renderer->viewport.y * renderer->dpi_scale.y);
238  event->tfinger.x = (event->tfinger.x / (renderer->scale.x * renderer->dpi_scale.x));
239  event->tfinger.y = (event->tfinger.y / (renderer->scale.y * renderer->dpi_scale.y));
240 
241  if (renderer->logical_w > 1) {
242  event->tfinger.x = event->tfinger.x / (renderer->logical_w - 1);
243  } else {
244  event->tfinger.x = 0.5f;
245  }
246  if (renderer->logical_h > 1) {
247  event->tfinger.y = event->tfinger.y / (renderer->logical_h - 1);
248  } else {
249  event->tfinger.y = 0.5f;
250  }
251  }
252  }
253 
254  return 0;
255 }
256 
257 int
260 {
263  width, height, window_flags);
264  if (!*window) {
265  *renderer = NULL;
266  return -1;
267  }
268 
269  *renderer = SDL_CreateRenderer(*window, -1, 0);
270  if (!*renderer) {
271  return -1;
272  }
273 
274  return 0;
275 }
276 
277 SDL_Renderer *
279 {
280 #if !SDL_RENDER_DISABLED
282  int n = SDL_GetNumRenderDrivers();
283  const char *hint;
284 
285  if (!window) {
286  SDL_SetError("Invalid window");
287  return NULL;
288  }
289 
290  if (SDL_GetRenderer(window)) {
291  SDL_SetError("Renderer already associated with window");
292  return NULL;
293  }
294 
297  flags |= SDL_RENDERER_PRESENTVSYNC;
298  } else {
299  flags &= ~SDL_RENDERER_PRESENTVSYNC;
300  }
301  }
302 
303  if (index < 0) {
305  if (hint) {
306  for (index = 0; index < n; ++index) {
307  const SDL_RenderDriver *driver = render_drivers[index];
308 
309  if (SDL_strcasecmp(hint, driver->info.name) == 0) {
310  /* Create a new renderer instance */
311  renderer = driver->CreateRenderer(window, flags);
312  break;
313  }
314  }
315  }
316 
317  if (!renderer) {
318  for (index = 0; index < n; ++index) {
319  const SDL_RenderDriver *driver = render_drivers[index];
320 
321  if ((driver->info.flags & flags) == flags) {
322  /* Create a new renderer instance */
323  renderer = driver->CreateRenderer(window, flags);
324  if (renderer) {
325  /* Yay, we got one! */
326  break;
327  }
328  }
329  }
330  }
331  if (index == n) {
332  SDL_SetError("Couldn't find matching render driver");
333  return NULL;
334  }
335  } else {
336  if (index >= SDL_GetNumRenderDrivers()) {
337  SDL_SetError("index must be -1 or in the range of 0 - %d",
339  return NULL;
340  }
341  /* Create a new renderer instance */
342  renderer = render_drivers[index]->CreateRenderer(window, flags);
343  }
344 
345  if (renderer) {
346  renderer->magic = &renderer_magic;
347  renderer->window = window;
348  renderer->scale.x = 1.0f;
349  renderer->scale.y = 1.0f;
350  renderer->dpi_scale.x = 1.0f;
351  renderer->dpi_scale.y = 1.0f;
352 
353  if (window && renderer->GetOutputSize) {
354  int window_w, window_h;
355  int output_w, output_h;
356  if (renderer->GetOutputSize(renderer, &output_w, &output_h) == 0) {
357  SDL_GetWindowSize(renderer->window, &window_w, &window_h);
358  renderer->dpi_scale.x = (float)window_w / output_w;
359  renderer->dpi_scale.y = (float)window_h / output_h;
360  }
361  }
362 
364  renderer->hidden = SDL_TRUE;
365  } else {
366  renderer->hidden = SDL_FALSE;
367  }
368 
369  SDL_SetWindowData(window, SDL_WINDOWRENDERDATA, renderer);
370 
371  SDL_RenderSetViewport(renderer, NULL);
372 
374 
376  "Created renderer: %s", renderer->info.name);
377  }
378  return renderer;
379 #else
380  SDL_SetError("SDL not built with rendering support");
381  return NULL;
382 #endif
383 }
384 
385 SDL_Renderer *
387 {
388 #if !SDL_RENDER_DISABLED
390 
391  renderer = SW_CreateRendererForSurface(surface);
392 
393  if (renderer) {
394  renderer->magic = &renderer_magic;
395  renderer->scale.x = 1.0f;
396  renderer->scale.y = 1.0f;
397 
398  SDL_RenderSetViewport(renderer, NULL);
399  }
400  return renderer;
401 #else
402  SDL_SetError("SDL not built with rendering support");
403  return NULL;
404 #endif /* !SDL_RENDER_DISABLED */
405 }
406 
407 SDL_Renderer *
409 {
411 }
412 
413 int
415 {
416  CHECK_RENDERER_MAGIC(renderer, -1);
417 
418  *info = renderer->info;
419  return 0;
420 }
421 
422 int
424 {
425  CHECK_RENDERER_MAGIC(renderer, -1);
426 
427  if (renderer->target) {
428  return SDL_QueryTexture(renderer->target, NULL, NULL, w, h);
429  } else if (renderer->GetOutputSize) {
430  return renderer->GetOutputSize(renderer, w, h);
431  } else if (renderer->window) {
432  SDL_GetWindowSize(renderer->window, w, h);
433  return 0;
434  } else {
435  SDL_assert(0 && "This should never happen");
436  return SDL_SetError("Renderer doesn't support querying output size");
437  }
438 }
439 
440 static SDL_bool
442 {
443  switch (blendMode)
444  {
445  /* These are required to be supported by all renderers */
446  case SDL_BLENDMODE_NONE:
447  case SDL_BLENDMODE_BLEND:
448  case SDL_BLENDMODE_ADD:
449  case SDL_BLENDMODE_MOD:
450  return SDL_TRUE;
451 
452  default:
453  return renderer->SupportsBlendMode && renderer->SupportsBlendMode(renderer, blendMode);
454  }
455 }
456 
457 static SDL_bool
459 {
460  Uint32 i;
461 
462  for (i = 0; i < renderer->info.num_texture_formats; ++i) {
463  if (renderer->info.texture_formats[i] == format) {
464  return SDL_TRUE;
465  }
466  }
467  return SDL_FALSE;
468 }
469 
470 static Uint32
472 {
473  Uint32 i;
474 
475  if (SDL_ISPIXELFORMAT_FOURCC(format)) {
476  /* Look for an exact match */
477  for (i = 0; i < renderer->info.num_texture_formats; ++i) {
478  if (renderer->info.texture_formats[i] == format) {
479  return renderer->info.texture_formats[i];
480  }
481  }
482  } else {
483  SDL_bool hasAlpha = SDL_ISPIXELFORMAT_ALPHA(format);
484 
485  /* We just want to match the first format that has the same channels */
486  for (i = 0; i < renderer->info.num_texture_formats; ++i) {
487  if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) &&
488  SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == hasAlpha) {
489  return renderer->info.texture_formats[i];
490  }
491  }
492  }
493  return renderer->info.texture_formats[0];
494 }
495 
496 SDL_Texture *
498 {
500 
501  CHECK_RENDERER_MAGIC(renderer, NULL);
502 
503  if (!format) {
504  format = renderer->info.texture_formats[0];
505  }
506  if (SDL_BYTESPERPIXEL(format) == 0) {
507  SDL_SetError("Invalid texture format");
508  return NULL;
509  }
510  if (SDL_ISPIXELFORMAT_INDEXED(format)) {
511  SDL_SetError("Palettized textures are not supported");
512  return NULL;
513  }
514  if (w <= 0 || h <= 0) {
515  SDL_SetError("Texture dimensions can't be 0");
516  return NULL;
517  }
518  if ((renderer->info.max_texture_width && w > renderer->info.max_texture_width) ||
519  (renderer->info.max_texture_height && h > renderer->info.max_texture_height)) {
520  SDL_SetError("Texture dimensions are limited to %dx%d", renderer->info.max_texture_width, renderer->info.max_texture_height);
521  return NULL;
522  }
523  texture = (SDL_Texture *) SDL_calloc(1, sizeof(*texture));
524  if (!texture) {
525  SDL_OutOfMemory();
526  return NULL;
527  }
528  texture->magic = &texture_magic;
529  texture->format = format;
530  texture->access = access;
531  texture->w = w;
532  texture->h = h;
533  texture->r = 255;
534  texture->g = 255;
535  texture->b = 255;
536  texture->a = 255;
537  texture->renderer = renderer;
538  texture->next = renderer->textures;
539  if (renderer->textures) {
540  renderer->textures->prev = texture;
541  }
542  renderer->textures = texture;
543 
544  if (IsSupportedFormat(renderer, format)) {
545  if (renderer->CreateTexture(renderer, texture) < 0) {
546  SDL_DestroyTexture(texture);
547  return NULL;
548  }
549  } else {
550  texture->native = SDL_CreateTexture(renderer,
551  GetClosestSupportedFormat(renderer, format),
552  access, w, h);
553  if (!texture->native) {
554  SDL_DestroyTexture(texture);
555  return NULL;
556  }
557 
558  /* Swap textures to have texture before texture->native in the list */
559  texture->native->next = texture->next;
560  if (texture->native->next) {
561  texture->native->next->prev = texture->native;
562  }
563  texture->prev = texture->native->prev;
564  if (texture->prev) {
565  texture->prev->next = texture;
566  }
567  texture->native->prev = texture;
568  texture->next = texture->native;
569  renderer->textures = texture;
570 
571  if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
572  texture->yuv = SDL_SW_CreateYUVTexture(format, w, h);
573  if (!texture->yuv) {
574  SDL_DestroyTexture(texture);
575  return NULL;
576  }
577  } else if (access == SDL_TEXTUREACCESS_STREAMING) {
578  /* The pitch is 4 byte aligned */
579  texture->pitch = (((w * SDL_BYTESPERPIXEL(format)) + 3) & ~3);
580  texture->pixels = SDL_calloc(1, texture->pitch * h);
581  if (!texture->pixels) {
582  SDL_DestroyTexture(texture);
583  return NULL;
584  }
585  }
586  }
587  return texture;
588 }
589 
590 SDL_Texture *
592 {
593  const SDL_PixelFormat *fmt;
594  SDL_bool needAlpha;
595  Uint32 i;
596  Uint32 format;
598 
599  CHECK_RENDERER_MAGIC(renderer, NULL);
600 
601  if (!surface) {
602  SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
603  return NULL;
604  }
605 
606  /* See what the best texture format is */
607  fmt = surface->format;
608  if (fmt->Amask || SDL_GetColorKey(surface, NULL) == 0) {
609  needAlpha = SDL_TRUE;
610  } else {
611  needAlpha = SDL_FALSE;
612  }
613  format = renderer->info.texture_formats[0];
614  for (i = 0; i < renderer->info.num_texture_formats; ++i) {
615  if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) &&
616  SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == needAlpha) {
617  format = renderer->info.texture_formats[i];
618  break;
619  }
620  }
621 
622  texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
623  surface->w, surface->h);
624  if (!texture) {
625  return NULL;
626  }
627 
628  if (format == surface->format->format) {
629  if (SDL_MUSTLOCK(surface)) {
630  SDL_LockSurface(surface);
631  SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
632  SDL_UnlockSurface(surface);
633  } else {
634  SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
635  }
636  } else {
637  SDL_PixelFormat *dst_fmt;
638  SDL_Surface *temp = NULL;
639 
640  /* Set up a destination surface for the texture update */
641  dst_fmt = SDL_AllocFormat(format);
642  if (!dst_fmt) {
643  SDL_DestroyTexture(texture);
644  return NULL;
645  }
646  temp = SDL_ConvertSurface(surface, dst_fmt, 0);
647  SDL_FreeFormat(dst_fmt);
648  if (temp) {
649  SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
650  SDL_FreeSurface(temp);
651  } else {
652  SDL_DestroyTexture(texture);
653  return NULL;
654  }
655  }
656 
657  {
658  Uint8 r, g, b, a;
660 
661  SDL_GetSurfaceColorMod(surface, &r, &g, &b);
662  SDL_SetTextureColorMod(texture, r, g, b);
663 
664  SDL_GetSurfaceAlphaMod(surface, &a);
665  SDL_SetTextureAlphaMod(texture, a);
666 
667  if (SDL_GetColorKey(surface, NULL) == 0) {
668  /* We converted to a texture with alpha format */
670  } else {
671  SDL_GetSurfaceBlendMode(surface, &blendMode);
672  SDL_SetTextureBlendMode(texture, blendMode);
673  }
674  }
675  return texture;
676 }
677 
678 int
680  int *w, int *h)
681 {
682  CHECK_TEXTURE_MAGIC(texture, -1);
683 
684  if (format) {
685  *format = texture->format;
686  }
687  if (access) {
688  *access = texture->access;
689  }
690  if (w) {
691  *w = texture->w;
692  }
693  if (h) {
694  *h = texture->h;
695  }
696  return 0;
697 }
698 
699 int
701 {
703 
704  CHECK_TEXTURE_MAGIC(texture, -1);
705 
706  renderer = texture->renderer;
707  if (r < 255 || g < 255 || b < 255) {
709  } else {
710  texture->modMode &= ~SDL_TEXTUREMODULATE_COLOR;
711  }
712  texture->r = r;
713  texture->g = g;
714  texture->b = b;
715  if (texture->native) {
716  return SDL_SetTextureColorMod(texture->native, r, g, b);
717  } else if (renderer->SetTextureColorMod) {
718  return renderer->SetTextureColorMod(renderer, texture);
719  } else {
720  return 0;
721  }
722 }
723 
724 int
726  Uint8 * b)
727 {
728  CHECK_TEXTURE_MAGIC(texture, -1);
729 
730  if (r) {
731  *r = texture->r;
732  }
733  if (g) {
734  *g = texture->g;
735  }
736  if (b) {
737  *b = texture->b;
738  }
739  return 0;
740 }
741 
742 int
744 {
746 
747  CHECK_TEXTURE_MAGIC(texture, -1);
748 
749  renderer = texture->renderer;
750  if (alpha < 255) {
752  } else {
753  texture->modMode &= ~SDL_TEXTUREMODULATE_ALPHA;
754  }
755  texture->a = alpha;
756  if (texture->native) {
757  return SDL_SetTextureAlphaMod(texture->native, alpha);
758  } else if (renderer->SetTextureAlphaMod) {
759  return renderer->SetTextureAlphaMod(renderer, texture);
760  } else {
761  return 0;
762  }
763 }
764 
765 int
767 {
768  CHECK_TEXTURE_MAGIC(texture, -1);
769 
770  if (alpha) {
771  *alpha = texture->a;
772  }
773  return 0;
774 }
775 
776 int
778 {
780 
781  CHECK_TEXTURE_MAGIC(texture, -1);
782 
783  renderer = texture->renderer;
784  if (!IsSupportedBlendMode(renderer, blendMode)) {
785  return SDL_Unsupported();
786  }
787  texture->blendMode = blendMode;
788  if (texture->native) {
789  return SDL_SetTextureBlendMode(texture->native, blendMode);
790  } else if (renderer->SetTextureBlendMode) {
791  return renderer->SetTextureBlendMode(renderer, texture);
792  } else {
793  return 0;
794  }
795 }
796 
797 int
799 {
800  CHECK_TEXTURE_MAGIC(texture, -1);
801 
802  if (blendMode) {
803  *blendMode = texture->blendMode;
804  }
805  return 0;
806 }
807 
808 static int
810  const void *pixels, int pitch)
811 {
812  SDL_Texture *native = texture->native;
813  SDL_Rect full_rect;
814 
815  if (SDL_SW_UpdateYUVTexture(texture->yuv, rect, pixels, pitch) < 0) {
816  return -1;
817  }
818 
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  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
826  /* We can lock the texture and copy to it */
827  void *native_pixels = NULL;
828  int native_pitch = 0;
829 
830  if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
831  return -1;
832  }
833  SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
834  rect->w, rect->h, native_pixels, native_pitch);
835  SDL_UnlockTexture(native);
836  } else {
837  /* Use a temporary buffer for updating */
838  const int temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3);
839  const size_t alloclen = rect->h * temp_pitch;
840  if (alloclen > 0) {
841  void *temp_pixels = SDL_malloc(alloclen);
842  if (!temp_pixels) {
843  return SDL_OutOfMemory();
844  }
845  SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
846  rect->w, rect->h, temp_pixels, temp_pitch);
847  SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch);
848  SDL_free(temp_pixels);
849  }
850  }
851  return 0;
852 }
853 
854 static int
856  const void *pixels, int pitch)
857 {
858  SDL_Texture *native = texture->native;
859 
860  if (!rect->w || !rect->h) {
861  return 0; /* nothing to do. */
862  }
863 
864  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
865  /* We can lock the texture and copy to it */
866  void *native_pixels = NULL;
867  int native_pitch = 0;
868 
869  if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
870  return -1;
871  }
872  SDL_ConvertPixels(rect->w, rect->h,
873  texture->format, pixels, pitch,
874  native->format, native_pixels, native_pitch);
875  SDL_UnlockTexture(native);
876  } else {
877  /* Use a temporary buffer for updating */
878  const int temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3);
879  const size_t alloclen = rect->h * temp_pitch;
880  if (alloclen > 0) {
881  void *temp_pixels = SDL_malloc(alloclen);
882  if (!temp_pixels) {
883  return SDL_OutOfMemory();
884  }
885  SDL_ConvertPixels(rect->w, rect->h,
886  texture->format, pixels, pitch,
887  native->format, temp_pixels, temp_pitch);
888  SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch);
889  SDL_free(temp_pixels);
890  }
891  }
892  return 0;
893 }
894 
895 int
897  const void *pixels, int pitch)
898 {
900  SDL_Rect full_rect;
901 
902  CHECK_TEXTURE_MAGIC(texture, -1);
903 
904  if (!pixels) {
905  return SDL_InvalidParamError("pixels");
906  }
907  if (!pitch) {
908  return SDL_InvalidParamError("pitch");
909  }
910 
911  if (!rect) {
912  full_rect.x = 0;
913  full_rect.y = 0;
914  full_rect.w = texture->w;
915  full_rect.h = texture->h;
916  rect = &full_rect;
917  }
918 
919  if ((rect->w == 0) || (rect->h == 0)) {
920  return 0; /* nothing to do. */
921  } else if (texture->yuv) {
922  return SDL_UpdateTextureYUV(texture, rect, pixels, pitch);
923  } else if (texture->native) {
924  return SDL_UpdateTextureNative(texture, rect, pixels, pitch);
925  } else {
926  renderer = texture->renderer;
927  return renderer->UpdateTexture(renderer, texture, rect, pixels, pitch);
928  }
929 }
930 
931 static int
933  const Uint8 *Yplane, int Ypitch,
934  const Uint8 *Uplane, int Upitch,
935  const Uint8 *Vplane, int Vpitch)
936 {
937  SDL_Texture *native = texture->native;
938  SDL_Rect full_rect;
939 
940  if (SDL_SW_UpdateYUVTexturePlanar(texture->yuv, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch) < 0) {
941  return -1;
942  }
943 
944  full_rect.x = 0;
945  full_rect.y = 0;
946  full_rect.w = texture->w;
947  full_rect.h = texture->h;
948  rect = &full_rect;
949 
950  if (!rect->w || !rect->h) {
951  return 0; /* nothing to do. */
952  }
953 
954  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
955  /* We can lock the texture and copy to it */
956  void *native_pixels = NULL;
957  int native_pitch = 0;
958 
959  if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
960  return -1;
961  }
962  SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
963  rect->w, rect->h, native_pixels, native_pitch);
964  SDL_UnlockTexture(native);
965  } else {
966  /* Use a temporary buffer for updating */
967  const int temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3);
968  const size_t alloclen = rect->h * temp_pitch;
969  if (alloclen > 0) {
970  void *temp_pixels = SDL_malloc(alloclen);
971  if (!temp_pixels) {
972  return SDL_OutOfMemory();
973  }
974  SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
975  rect->w, rect->h, temp_pixels, temp_pitch);
976  SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch);
977  SDL_free(temp_pixels);
978  }
979  }
980  return 0;
981 }
982 
984  const Uint8 *Yplane, int Ypitch,
985  const Uint8 *Uplane, int Upitch,
986  const Uint8 *Vplane, int Vpitch)
987 {
989  SDL_Rect full_rect;
990 
991  CHECK_TEXTURE_MAGIC(texture, -1);
992 
993  if (!Yplane) {
994  return SDL_InvalidParamError("Yplane");
995  }
996  if (!Ypitch) {
997  return SDL_InvalidParamError("Ypitch");
998  }
999  if (!Uplane) {
1000  return SDL_InvalidParamError("Uplane");
1001  }
1002  if (!Upitch) {
1003  return SDL_InvalidParamError("Upitch");
1004  }
1005  if (!Vplane) {
1006  return SDL_InvalidParamError("Vplane");
1007  }
1008  if (!Vpitch) {
1009  return SDL_InvalidParamError("Vpitch");
1010  }
1011 
1012  if (texture->format != SDL_PIXELFORMAT_YV12 &&
1013  texture->format != SDL_PIXELFORMAT_IYUV) {
1014  return SDL_SetError("Texture format must by YV12 or IYUV");
1015  }
1016 
1017  if (!rect) {
1018  full_rect.x = 0;
1019  full_rect.y = 0;
1020  full_rect.w = texture->w;
1021  full_rect.h = texture->h;
1022  rect = &full_rect;
1023  }
1024 
1025  if (!rect->w || !rect->h) {
1026  return 0; /* nothing to do. */
1027  }
1028 
1029  if (texture->yuv) {
1030  return SDL_UpdateTextureYUVPlanar(texture, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
1031  } else {
1032  SDL_assert(!texture->native);
1033  renderer = texture->renderer;
1034  SDL_assert(renderer->UpdateTextureYUV);
1035  if (renderer->UpdateTextureYUV) {
1036  return renderer->UpdateTextureYUV(renderer, texture, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
1037  } else {
1038  return SDL_Unsupported();
1039  }
1040  }
1041 }
1042 
1043 static int
1045  void **pixels, int *pitch)
1046 {
1047  return SDL_SW_LockYUVTexture(texture->yuv, rect, pixels, pitch);
1048 }
1049 
1050 static int
1052  void **pixels, int *pitch)
1053 {
1054  texture->locked_rect = *rect;
1055  *pixels = (void *) ((Uint8 *) texture->pixels +
1056  rect->y * texture->pitch +
1057  rect->x * SDL_BYTESPERPIXEL(texture->format));
1058  *pitch = texture->pitch;
1059  return 0;
1060 }
1061 
1062 int
1064  void **pixels, int *pitch)
1065 {
1067  SDL_Rect full_rect;
1068 
1069  CHECK_TEXTURE_MAGIC(texture, -1);
1070 
1071  if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
1072  return SDL_SetError("SDL_LockTexture(): texture must be streaming");
1073  }
1074 
1075  if (!rect) {
1076  full_rect.x = 0;
1077  full_rect.y = 0;
1078  full_rect.w = texture->w;
1079  full_rect.h = texture->h;
1080  rect = &full_rect;
1081  }
1082 
1083  if (texture->yuv) {
1084  return SDL_LockTextureYUV(texture, rect, pixels, pitch);
1085  } else if (texture->native) {
1086  return SDL_LockTextureNative(texture, rect, pixels, pitch);
1087  } else {
1088  renderer = texture->renderer;
1089  return renderer->LockTexture(renderer, texture, rect, pixels, pitch);
1090  }
1091 }
1092 
1093 static void
1095 {
1096  SDL_Texture *native = texture->native;
1097  void *native_pixels = NULL;
1098  int native_pitch = 0;
1099  SDL_Rect rect;
1100 
1101  rect.x = 0;
1102  rect.y = 0;
1103  rect.w = texture->w;
1104  rect.h = texture->h;
1105 
1106  if (SDL_LockTexture(native, &rect, &native_pixels, &native_pitch) < 0) {
1107  return;
1108  }
1109  SDL_SW_CopyYUVToRGB(texture->yuv, &rect, native->format,
1110  rect.w, rect.h, native_pixels, native_pitch);
1111  SDL_UnlockTexture(native);
1112 }
1113 
1114 static void
1116 {
1117  SDL_Texture *native = texture->native;
1118  void *native_pixels = NULL;
1119  int native_pitch = 0;
1120  const SDL_Rect *rect = &texture->locked_rect;
1121  const void* pixels = (void *) ((Uint8 *) texture->pixels +
1122  rect->y * texture->pitch +
1123  rect->x * SDL_BYTESPERPIXEL(texture->format));
1124  int pitch = texture->pitch;
1125 
1126  if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
1127  return;
1128  }
1129  SDL_ConvertPixels(rect->w, rect->h,
1130  texture->format, pixels, pitch,
1131  native->format, native_pixels, native_pitch);
1132  SDL_UnlockTexture(native);
1133 }
1134 
1135 void
1137 {
1139 
1140  CHECK_TEXTURE_MAGIC(texture, );
1141 
1142  if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
1143  return;
1144  }
1145  if (texture->yuv) {
1146  SDL_UnlockTextureYUV(texture);
1147  } else if (texture->native) {
1148  SDL_UnlockTextureNative(texture);
1149  } else {
1150  renderer = texture->renderer;
1151  renderer->UnlockTexture(renderer, texture);
1152  }
1153 }
1154 
1155 SDL_bool
1157 {
1158  if (!renderer || !renderer->SetRenderTarget) {
1159  return SDL_FALSE;
1160  }
1161  return (renderer->info.flags & SDL_RENDERER_TARGETTEXTURE) != 0;
1162 }
1163 
1164 int
1166 {
1167  if (!SDL_RenderTargetSupported(renderer)) {
1168  return SDL_Unsupported();
1169  }
1170  if (texture == renderer->target) {
1171  /* Nothing to do! */
1172  return 0;
1173  }
1174 
1175  /* texture == NULL is valid and means reset the target to the window */
1176  if (texture) {
1177  CHECK_TEXTURE_MAGIC(texture, -1);
1178  if (renderer != texture->renderer) {
1179  return SDL_SetError("Texture was not created with this renderer");
1180  }
1181  if (texture->access != SDL_TEXTUREACCESS_TARGET) {
1182  return SDL_SetError("Texture not created with SDL_TEXTUREACCESS_TARGET");
1183  }
1184  if (texture->native) {
1185  /* Always render to the native texture */
1186  texture = texture->native;
1187  }
1188  }
1189 
1190  if (texture && !renderer->target) {
1191  /* Make a backup of the viewport */
1192  renderer->viewport_backup = renderer->viewport;
1193  renderer->clip_rect_backup = renderer->clip_rect;
1194  renderer->clipping_enabled_backup = renderer->clipping_enabled;
1195  renderer->scale_backup = renderer->scale;
1196  renderer->logical_w_backup = renderer->logical_w;
1197  renderer->logical_h_backup = renderer->logical_h;
1198  }
1199  renderer->target = texture;
1200 
1201  if (renderer->SetRenderTarget(renderer, texture) < 0) {
1202  return -1;
1203  }
1204 
1205  if (texture) {
1206  renderer->viewport.x = 0;
1207  renderer->viewport.y = 0;
1208  renderer->viewport.w = texture->w;
1209  renderer->viewport.h = texture->h;
1210  SDL_zero(renderer->clip_rect);
1211  renderer->clipping_enabled = SDL_FALSE;
1212  renderer->scale.x = 1.0f;
1213  renderer->scale.y = 1.0f;
1214  renderer->logical_w = texture->w;
1215  renderer->logical_h = texture->h;
1216  } else {
1217  renderer->viewport = renderer->viewport_backup;
1218  renderer->clip_rect = renderer->clip_rect_backup;
1219  renderer->clipping_enabled = renderer->clipping_enabled_backup;
1220  renderer->scale = renderer->scale_backup;
1221  renderer->logical_w = renderer->logical_w_backup;
1222  renderer->logical_h = renderer->logical_h_backup;
1223  }
1224  if (renderer->UpdateViewport(renderer) < 0) {
1225  return -1;
1226  }
1227  if (renderer->UpdateClipRect(renderer) < 0) {
1228  return -1;
1229  }
1230 
1231  /* All set! */
1232  return 0;
1233 }
1234 
1235 SDL_Texture *
1237 {
1238  return renderer->target;
1239 }
1240 
1241 static int
1243 {
1244  int w = 1, h = 1;
1245  float want_aspect;
1246  float real_aspect;
1247  float scale;
1249  /* 0 is for letterbox, 1 is for overscan */
1250  int scale_policy = 0;
1251  const char *hint;
1252 
1253  if (!renderer->logical_w || !renderer->logical_h) {
1254  return 0;
1255  }
1256  if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) {
1257  return -1;
1258  }
1259 
1261  if (hint && (*hint == '1' || SDL_strcasecmp(hint, "overscan") == 0)) {
1262  SDL_bool overscan_supported = SDL_TRUE;
1263  /* Unfortunately, Direct3D 9 doesn't support negative viewport numbers
1264  which the overscan implementation relies on.
1265  */
1266  if (SDL_strcasecmp(SDL_GetCurrentVideoDriver(), "direct3d") == 0) {
1267  overscan_supported = SDL_FALSE;
1268  }
1269  if (overscan_supported) {
1270  scale_policy = 1;
1271  }
1272  }
1273 
1274  want_aspect = (float)renderer->logical_w / renderer->logical_h;
1275  real_aspect = (float)w / h;
1276 
1277  /* Clear the scale because we're setting viewport in output coordinates */
1278  SDL_RenderSetScale(renderer, 1.0f, 1.0f);
1279 
1280  if (renderer->integer_scale) {
1281  if (want_aspect > real_aspect) {
1282  scale = (float)(w / renderer->logical_w);
1283  } else {
1284  scale = (float)(h / renderer->logical_h);
1285  }
1286  viewport.w = (int)SDL_ceil(renderer->logical_w * scale);
1287  viewport.x = (w - viewport.w) / 2;
1288  viewport.h = (int)SDL_ceil(renderer->logical_h * scale);
1289  viewport.y = (h - viewport.h) / 2;
1290 
1291  SDL_RenderSetViewport(renderer, &viewport);
1292  } else if (SDL_fabs(want_aspect-real_aspect) < 0.0001) {
1293  /* The aspect ratios are the same, just scale appropriately */
1294  scale = (float)w / renderer->logical_w;
1295  SDL_RenderSetViewport(renderer, NULL);
1296  } else if (want_aspect > real_aspect) {
1297  if (scale_policy == 1) {
1298  /* We want a wider aspect ratio than is available -
1299  zoom so logical height matches the real height
1300  and the width will grow off the screen
1301  */
1302  scale = (float)h / renderer->logical_h;
1303  viewport.y = 0;
1304  viewport.h = h;
1305  viewport.w = (int)SDL_ceil(renderer->logical_w * scale);
1306  viewport.x = (w - viewport.w) / 2;
1307  SDL_RenderSetViewport(renderer, &viewport);
1308  } else {
1309  /* We want a wider aspect ratio than is available - letterbox it */
1310  scale = (float)w / renderer->logical_w;
1311  viewport.x = 0;
1312  viewport.w = w;
1313  viewport.h = (int)SDL_ceil(renderer->logical_h * scale);
1314  viewport.y = (h - viewport.h) / 2;
1315  SDL_RenderSetViewport(renderer, &viewport);
1316  }
1317  } else {
1318  if (scale_policy == 1) {
1319  /* We want a narrower aspect ratio than is available -
1320  zoom so logical width matches the real width
1321  and the height will grow off the screen
1322  */
1323  scale = (float)w / renderer->logical_w;
1324  viewport.x = 0;
1325  viewport.w = w;
1326  viewport.h = (int)SDL_ceil(renderer->logical_h * scale);
1327  viewport.y = (h - viewport.h) / 2;
1328  SDL_RenderSetViewport(renderer, &viewport);
1329  } else {
1330  /* We want a narrower aspect ratio than is available - use side-bars */
1331  scale = (float)h / renderer->logical_h;
1332  viewport.y = 0;
1333  viewport.h = h;
1334  viewport.w = (int)SDL_ceil(renderer->logical_w * scale);
1335  viewport.x = (w - viewport.w) / 2;
1336  SDL_RenderSetViewport(renderer, &viewport);
1337  }
1338  }
1339 
1340  /* Set the new scale */
1341  SDL_RenderSetScale(renderer, scale, scale);
1342 
1343  return 0;
1344 }
1345 
1346 int
1348 {
1349  CHECK_RENDERER_MAGIC(renderer, -1);
1350 
1351  if (!w || !h) {
1352  /* Clear any previous logical resolution */
1353  renderer->logical_w = 0;
1354  renderer->logical_h = 0;
1355  SDL_RenderSetViewport(renderer, NULL);
1356  SDL_RenderSetScale(renderer, 1.0f, 1.0f);
1357  return 0;
1358  }
1359 
1360  renderer->logical_w = w;
1361  renderer->logical_h = h;
1362 
1363  return UpdateLogicalSize(renderer);
1364 }
1365 
1366 void
1368 {
1369  CHECK_RENDERER_MAGIC(renderer, );
1370 
1371  if (w) {
1372  *w = renderer->logical_w;
1373  }
1374  if (h) {
1375  *h = renderer->logical_h;
1376  }
1377 }
1378 
1379 int
1381 {
1382  CHECK_RENDERER_MAGIC(renderer, -1);
1383 
1384  renderer->integer_scale = enable;
1385 
1386  return UpdateLogicalSize(renderer);
1387 }
1388 
1389 SDL_bool
1391 {
1392  CHECK_RENDERER_MAGIC(renderer, SDL_FALSE);
1393 
1394  return renderer->integer_scale;
1395 }
1396 
1397 int
1399 {
1400  CHECK_RENDERER_MAGIC(renderer, -1);
1401 
1402  if (rect) {
1403  renderer->viewport.x = (int)SDL_floor(rect->x * renderer->scale.x);
1404  renderer->viewport.y = (int)SDL_floor(rect->y * renderer->scale.y);
1405  renderer->viewport.w = (int)SDL_ceil(rect->w * renderer->scale.x);
1406  renderer->viewport.h = (int)SDL_ceil(rect->h * renderer->scale.y);
1407  } else {
1408  renderer->viewport.x = 0;
1409  renderer->viewport.y = 0;
1410  if (SDL_GetRendererOutputSize(renderer, &renderer->viewport.w, &renderer->viewport.h) < 0) {
1411  return -1;
1412  }
1413  }
1414  return renderer->UpdateViewport(renderer);
1415 }
1416 
1417 void
1419 {
1420  CHECK_RENDERER_MAGIC(renderer, );
1421 
1422  if (rect) {
1423  rect->x = (int)(renderer->viewport.x / renderer->scale.x);
1424  rect->y = (int)(renderer->viewport.y / renderer->scale.y);
1425  rect->w = (int)(renderer->viewport.w / renderer->scale.x);
1426  rect->h = (int)(renderer->viewport.h / renderer->scale.y);
1427  }
1428 }
1429 
1430 int
1432 {
1433  CHECK_RENDERER_MAGIC(renderer, -1)
1434 
1435  if (rect) {
1436  renderer->clipping_enabled = SDL_TRUE;
1437  renderer->clip_rect.x = (int)SDL_floor(rect->x * renderer->scale.x);
1438  renderer->clip_rect.y = (int)SDL_floor(rect->y * renderer->scale.y);
1439  renderer->clip_rect.w = (int)SDL_ceil(rect->w * renderer->scale.x);
1440  renderer->clip_rect.h = (int)SDL_ceil(rect->h * renderer->scale.y);
1441  } else {
1442  renderer->clipping_enabled = SDL_FALSE;
1443  SDL_zero(renderer->clip_rect);
1444  }
1445  return renderer->UpdateClipRect(renderer);
1446 }
1447 
1448 void
1450 {
1451  CHECK_RENDERER_MAGIC(renderer, )
1452 
1453  if (rect) {
1454  rect->x = (int)(renderer->clip_rect.x / renderer->scale.x);
1455  rect->y = (int)(renderer->clip_rect.y / renderer->scale.y);
1456  rect->w = (int)(renderer->clip_rect.w / renderer->scale.x);
1457  rect->h = (int)(renderer->clip_rect.h / renderer->scale.y);
1458  }
1459 }
1460 
1461 SDL_bool
1463 {
1464  CHECK_RENDERER_MAGIC(renderer, SDL_FALSE)
1465  return renderer->clipping_enabled;
1466 }
1467 
1468 int
1469 SDL_RenderSetScale(SDL_Renderer * renderer, float scaleX, float scaleY)
1470 {
1471  CHECK_RENDERER_MAGIC(renderer, -1);
1472 
1473  renderer->scale.x = scaleX;
1474  renderer->scale.y = scaleY;
1475  return 0;
1476 }
1477 
1478 void
1479 SDL_RenderGetScale(SDL_Renderer * renderer, float *scaleX, float *scaleY)
1480 {
1481  CHECK_RENDERER_MAGIC(renderer, );
1482 
1483  if (scaleX) {
1484  *scaleX = renderer->scale.x;
1485  }
1486  if (scaleY) {
1487  *scaleY = renderer->scale.y;
1488  }
1489 }
1490 
1491 int
1493  Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1494 {
1495  CHECK_RENDERER_MAGIC(renderer, -1);
1496 
1497  renderer->r = r;
1498  renderer->g = g;
1499  renderer->b = b;
1500  renderer->a = a;
1501  return 0;
1502 }
1503 
1504 int
1506  Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a)
1507 {
1508  CHECK_RENDERER_MAGIC(renderer, -1);
1509 
1510  if (r) {
1511  *r = renderer->r;
1512  }
1513  if (g) {
1514  *g = renderer->g;
1515  }
1516  if (b) {
1517  *b = renderer->b;
1518  }
1519  if (a) {
1520  *a = renderer->a;
1521  }
1522  return 0;
1523 }
1524 
1525 int
1527 {
1528  CHECK_RENDERER_MAGIC(renderer, -1);
1529 
1530  if (!IsSupportedBlendMode(renderer, blendMode)) {
1531  return SDL_Unsupported();
1532  }
1533  renderer->blendMode = blendMode;
1534  return 0;
1535 }
1536 
1537 int
1539 {
1540  CHECK_RENDERER_MAGIC(renderer, -1);
1541 
1542  *blendMode = renderer->blendMode;
1543  return 0;
1544 }
1545 
1546 int
1548 {
1549  CHECK_RENDERER_MAGIC(renderer, -1);
1550 
1551  /* Don't draw while we're hidden */
1552  if (renderer->hidden) {
1553  return 0;
1554  }
1555  return renderer->RenderClear(renderer);
1556 }
1557 
1558 int
1560 {
1561  SDL_Point point;
1562 
1563  point.x = x;
1564  point.y = y;
1565  return SDL_RenderDrawPoints(renderer, &point, 1);
1566 }
1567 
1568 static int
1570  const SDL_Point * points, int count)
1571 {
1572  SDL_FRect *frects;
1573  int i;
1574  int status;
1575 
1576  frects = SDL_stack_alloc(SDL_FRect, count);
1577  if (!frects) {
1578  return SDL_OutOfMemory();
1579  }
1580  for (i = 0; i < count; ++i) {
1581  frects[i].x = points[i].x * renderer->scale.x;
1582  frects[i].y = points[i].y * renderer->scale.y;
1583  frects[i].w = renderer->scale.x;
1584  frects[i].h = renderer->scale.y;
1585  }
1586 
1587  status = renderer->RenderFillRects(renderer, frects, count);
1588 
1589  SDL_stack_free(frects);
1590 
1591  return status;
1592 }
1593 
1594 int
1596  const SDL_Point * points, int count)
1597 {
1598  SDL_FPoint *fpoints;
1599  int i;
1600  int status;
1601 
1602  CHECK_RENDERER_MAGIC(renderer, -1);
1603 
1604  if (!points) {
1605  return SDL_SetError("SDL_RenderDrawPoints(): Passed NULL points");
1606  }
1607  if (count < 1) {
1608  return 0;
1609  }
1610 
1611  /* Don't draw while we're hidden */
1612  if (renderer->hidden) {
1613  return 0;
1614  }
1615 
1616  if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
1617  return RenderDrawPointsWithRects(renderer, points, count);
1618  }
1619 
1620  fpoints = SDL_stack_alloc(SDL_FPoint, count);
1621  if (!fpoints) {
1622  return SDL_OutOfMemory();
1623  }
1624  for (i = 0; i < count; ++i) {
1625  fpoints[i].x = points[i].x * renderer->scale.x;
1626  fpoints[i].y = points[i].y * renderer->scale.y;
1627  }
1628 
1629  status = renderer->RenderDrawPoints(renderer, fpoints, count);
1630 
1631  SDL_stack_free(fpoints);
1632 
1633  return status;
1634 }
1635 
1636 int
1638 {
1639  SDL_Point points[2];
1640 
1641  points[0].x = x1;
1642  points[0].y = y1;
1643  points[1].x = x2;
1644  points[1].y = y2;
1645  return SDL_RenderDrawLines(renderer, points, 2);
1646 }
1647 
1648 static int
1650  const SDL_Point * points, int count)
1651 {
1652  SDL_FRect *frect;
1653  SDL_FRect *frects;
1654  SDL_FPoint fpoints[2];
1655  int i, nrects;
1656  int status;
1657 
1658  frects = SDL_stack_alloc(SDL_FRect, count-1);
1659  if (!frects) {
1660  return SDL_OutOfMemory();
1661  }
1662 
1663  status = 0;
1664  nrects = 0;
1665  for (i = 0; i < count-1; ++i) {
1666  if (points[i].x == points[i+1].x) {
1667  int minY = SDL_min(points[i].y, points[i+1].y);
1668  int maxY = SDL_max(points[i].y, points[i+1].y);
1669 
1670  frect = &frects[nrects++];
1671  frect->x = points[i].x * renderer->scale.x;
1672  frect->y = minY * renderer->scale.y;
1673  frect->w = renderer->scale.x;
1674  frect->h = (maxY - minY + 1) * renderer->scale.y;
1675  } else if (points[i].y == points[i+1].y) {
1676  int minX = SDL_min(points[i].x, points[i+1].x);
1677  int maxX = SDL_max(points[i].x, points[i+1].x);
1678 
1679  frect = &frects[nrects++];
1680  frect->x = minX * renderer->scale.x;
1681  frect->y = points[i].y * renderer->scale.y;
1682  frect->w = (maxX - minX + 1) * renderer->scale.x;
1683  frect->h = renderer->scale.y;
1684  } else {
1685  /* FIXME: We can't use a rect for this line... */
1686  fpoints[0].x = points[i].x * renderer->scale.x;
1687  fpoints[0].y = points[i].y * renderer->scale.y;
1688  fpoints[1].x = points[i+1].x * renderer->scale.x;
1689  fpoints[1].y = points[i+1].y * renderer->scale.y;
1690  status += renderer->RenderDrawLines(renderer, fpoints, 2);
1691  }
1692  }
1693 
1694  status += renderer->RenderFillRects(renderer, frects, nrects);
1695 
1696  SDL_stack_free(frects);
1697 
1698  if (status < 0) {
1699  status = -1;
1700  }
1701  return status;
1702 }
1703 
1704 int
1706  const SDL_Point * points, int count)
1707 {
1708  SDL_FPoint *fpoints;
1709  int i;
1710  int status;
1711 
1712  CHECK_RENDERER_MAGIC(renderer, -1);
1713 
1714  if (!points) {
1715  return SDL_SetError("SDL_RenderDrawLines(): Passed NULL points");
1716  }
1717  if (count < 2) {
1718  return 0;
1719  }
1720 
1721  /* Don't draw while we're hidden */
1722  if (renderer->hidden) {
1723  return 0;
1724  }
1725 
1726  if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
1727  return RenderDrawLinesWithRects(renderer, points, count);
1728  }
1729 
1730  fpoints = SDL_stack_alloc(SDL_FPoint, count);
1731  if (!fpoints) {
1732  return SDL_OutOfMemory();
1733  }
1734  for (i = 0; i < count; ++i) {
1735  fpoints[i].x = points[i].x * renderer->scale.x;
1736  fpoints[i].y = points[i].y * renderer->scale.y;
1737  }
1738 
1739  status = renderer->RenderDrawLines(renderer, fpoints, count);
1740 
1741  SDL_stack_free(fpoints);
1742 
1743  return status;
1744 }
1745 
1746 int
1748 {
1749  SDL_Rect full_rect;
1750  SDL_Point points[5];
1751 
1752  CHECK_RENDERER_MAGIC(renderer, -1);
1753 
1754  /* If 'rect' == NULL, then outline the whole surface */
1755  if (!rect) {
1756  SDL_RenderGetViewport(renderer, &full_rect);
1757  full_rect.x = 0;
1758  full_rect.y = 0;
1759  rect = &full_rect;
1760  }
1761 
1762  points[0].x = rect->x;
1763  points[0].y = rect->y;
1764  points[1].x = rect->x+rect->w-1;
1765  points[1].y = rect->y;
1766  points[2].x = rect->x+rect->w-1;
1767  points[2].y = rect->y+rect->h-1;
1768  points[3].x = rect->x;
1769  points[3].y = rect->y+rect->h-1;
1770  points[4].x = rect->x;
1771  points[4].y = rect->y;
1772  return SDL_RenderDrawLines(renderer, points, 5);
1773 }
1774 
1775 int
1777  const SDL_Rect * rects, int count)
1778 {
1779  int i;
1780 
1781  CHECK_RENDERER_MAGIC(renderer, -1);
1782 
1783  if (!rects) {
1784  return SDL_SetError("SDL_RenderDrawRects(): Passed NULL rects");
1785  }
1786  if (count < 1) {
1787  return 0;
1788  }
1789 
1790  /* Don't draw while we're hidden */
1791  if (renderer->hidden) {
1792  return 0;
1793  }
1794 
1795  for (i = 0; i < count; ++i) {
1796  if (SDL_RenderDrawRect(renderer, &rects[i]) < 0) {
1797  return -1;
1798  }
1799  }
1800  return 0;
1801 }
1802 
1803 int
1805 {
1806  SDL_Rect full_rect = { 0, 0, 0, 0 };
1807 
1808  CHECK_RENDERER_MAGIC(renderer, -1);
1809 
1810  /* If 'rect' == NULL, then outline the whole surface */
1811  if (!rect) {
1812  SDL_RenderGetViewport(renderer, &full_rect);
1813  full_rect.x = 0;
1814  full_rect.y = 0;
1815  rect = &full_rect;
1816  }
1817  return SDL_RenderFillRects(renderer, rect, 1);
1818 }
1819 
1820 int
1822  const SDL_Rect * rects, int count)
1823 {
1824  SDL_FRect *frects;
1825  int i;
1826  int status;
1827 
1828  CHECK_RENDERER_MAGIC(renderer, -1);
1829 
1830  if (!rects) {
1831  return SDL_SetError("SDL_RenderFillRects(): Passed NULL rects");
1832  }
1833  if (count < 1) {
1834  return 0;
1835  }
1836 
1837  /* Don't draw while we're hidden */
1838  if (renderer->hidden) {
1839  return 0;
1840  }
1841 
1842  frects = SDL_stack_alloc(SDL_FRect, count);
1843  if (!frects) {
1844  return SDL_OutOfMemory();
1845  }
1846  for (i = 0; i < count; ++i) {
1847  frects[i].x = rects[i].x * renderer->scale.x;
1848  frects[i].y = rects[i].y * renderer->scale.y;
1849  frects[i].w = rects[i].w * renderer->scale.x;
1850  frects[i].h = rects[i].h * renderer->scale.y;
1851  }
1852 
1853  status = renderer->RenderFillRects(renderer, frects, count);
1854 
1855  SDL_stack_free(frects);
1856 
1857  return status;
1858 }
1859 
1860 int
1862  const SDL_Rect * srcrect, const SDL_Rect * dstrect)
1863 {
1864  SDL_Rect real_srcrect = { 0, 0, 0, 0 };
1865  SDL_Rect real_dstrect = { 0, 0, 0, 0 };
1866  SDL_FRect frect;
1867 
1868  CHECK_RENDERER_MAGIC(renderer, -1);
1869  CHECK_TEXTURE_MAGIC(texture, -1);
1870 
1871  if (renderer != texture->renderer) {
1872  return SDL_SetError("Texture was not created with this renderer");
1873  }
1874 
1875  /* Don't draw while we're hidden */
1876  if (renderer->hidden) {
1877  return 0;
1878  }
1879 
1880  real_srcrect.x = 0;
1881  real_srcrect.y = 0;
1882  real_srcrect.w = texture->w;
1883  real_srcrect.h = texture->h;
1884  if (srcrect) {
1885  if (!SDL_IntersectRect(srcrect, &real_srcrect, &real_srcrect)) {
1886  return 0;
1887  }
1888  }
1889 
1890  SDL_RenderGetViewport(renderer, &real_dstrect);
1891  real_dstrect.x = 0;
1892  real_dstrect.y = 0;
1893  if (dstrect) {
1894  if (!SDL_HasIntersection(dstrect, &real_dstrect)) {
1895  return 0;
1896  }
1897  real_dstrect = *dstrect;
1898  }
1899 
1900  if (texture->native) {
1901  texture = texture->native;
1902  }
1903 
1904  frect.x = real_dstrect.x * renderer->scale.x;
1905  frect.y = real_dstrect.y * renderer->scale.y;
1906  frect.w = real_dstrect.w * renderer->scale.x;
1907  frect.h = real_dstrect.h * renderer->scale.y;
1908 
1909  return renderer->RenderCopy(renderer, texture, &real_srcrect, &frect);
1910 }
1911 
1912 
1913 int
1915  const SDL_Rect * srcrect, const SDL_Rect * dstrect,
1916  const double angle, const SDL_Point *center, const SDL_RendererFlip flip)
1917 {
1918  SDL_Rect real_srcrect = { 0, 0, 0, 0 };
1919  SDL_Rect real_dstrect = { 0, 0, 0, 0 };
1920  SDL_Point real_center;
1921  SDL_FRect frect;
1922  SDL_FPoint fcenter;
1923 
1924  if (flip == SDL_FLIP_NONE && (int)(angle/360) == angle/360) { /* fast path when we don't need rotation or flipping */
1925  return SDL_RenderCopy(renderer, texture, srcrect, dstrect);
1926  }
1927 
1928  CHECK_RENDERER_MAGIC(renderer, -1);
1929  CHECK_TEXTURE_MAGIC(texture, -1);
1930 
1931  if (renderer != texture->renderer) {
1932  return SDL_SetError("Texture was not created with this renderer");
1933  }
1934  if (!renderer->RenderCopyEx) {
1935  return SDL_SetError("Renderer does not support RenderCopyEx");
1936  }
1937 
1938  /* Don't draw while we're hidden */
1939  if (renderer->hidden) {
1940  return 0;
1941  }
1942 
1943  real_srcrect.x = 0;
1944  real_srcrect.y = 0;
1945  real_srcrect.w = texture->w;
1946  real_srcrect.h = texture->h;
1947  if (srcrect) {
1948  if (!SDL_IntersectRect(srcrect, &real_srcrect, &real_srcrect)) {
1949  return 0;
1950  }
1951  }
1952 
1953  /* We don't intersect the dstrect with the viewport as RenderCopy does because of potential rotation clipping issues... TODO: should we? */
1954  if (dstrect) {
1955  real_dstrect = *dstrect;
1956  } else {
1957  SDL_RenderGetViewport(renderer, &real_dstrect);
1958  real_dstrect.x = 0;
1959  real_dstrect.y = 0;
1960  }
1961 
1962  if (texture->native) {
1963  texture = texture->native;
1964  }
1965 
1966  if (center) {
1967  real_center = *center;
1968  } else {
1969  real_center.x = real_dstrect.w/2;
1970  real_center.y = real_dstrect.h/2;
1971  }
1972 
1973  frect.x = real_dstrect.x * renderer->scale.x;
1974  frect.y = real_dstrect.y * renderer->scale.y;
1975  frect.w = real_dstrect.w * renderer->scale.x;
1976  frect.h = real_dstrect.h * renderer->scale.y;
1977 
1978  fcenter.x = real_center.x * renderer->scale.x;
1979  fcenter.y = real_center.y * renderer->scale.y;
1980 
1981  return renderer->RenderCopyEx(renderer, texture, &real_srcrect, &frect, angle, &fcenter, flip);
1982 }
1983 
1984 int
1986  Uint32 format, void * pixels, int pitch)
1987 {
1988  SDL_Rect real_rect;
1989 
1990  CHECK_RENDERER_MAGIC(renderer, -1);
1991 
1992  if (!renderer->RenderReadPixels) {
1993  return SDL_Unsupported();
1994  }
1995 
1996  if (!format) {
1997  format = SDL_GetWindowPixelFormat(renderer->window);
1998  }
1999 
2000  real_rect.x = renderer->viewport.x;
2001  real_rect.y = renderer->viewport.y;
2002  real_rect.w = renderer->viewport.w;
2003  real_rect.h = renderer->viewport.h;
2004  if (rect) {
2005  if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
2006  return 0;
2007  }
2008  if (real_rect.y > rect->y) {
2009  pixels = (Uint8 *)pixels + pitch * (real_rect.y - rect->y);
2010  }
2011  if (real_rect.x > rect->x) {
2012  int bpp = SDL_BYTESPERPIXEL(format);
2013  pixels = (Uint8 *)pixels + bpp * (real_rect.x - rect->x);
2014  }
2015  }
2016 
2017  return renderer->RenderReadPixels(renderer, &real_rect,
2018  format, pixels, pitch);
2019 }
2020 
2021 void
2023 {
2024  CHECK_RENDERER_MAGIC(renderer, );
2025 
2026  /* Don't draw while we're hidden */
2027  if (renderer->hidden) {
2028  return;
2029  }
2030  renderer->RenderPresent(renderer);
2031 }
2032 
2033 void
2035 {
2037 
2038  CHECK_TEXTURE_MAGIC(texture, );
2039 
2040  renderer = texture->renderer;
2041  if (texture == renderer->target) {
2042  SDL_SetRenderTarget(renderer, NULL);
2043  }
2044 
2045  texture->magic = NULL;
2046 
2047  if (texture->next) {
2048  texture->next->prev = texture->prev;
2049  }
2050  if (texture->prev) {
2051  texture->prev->next = texture->next;
2052  } else {
2053  renderer->textures = texture->next;
2054  }
2055 
2056  if (texture->native) {
2057  SDL_DestroyTexture(texture->native);
2058  }
2059  if (texture->yuv) {
2060  SDL_SW_DestroyYUVTexture(texture->yuv);
2061  }
2062  SDL_free(texture->pixels);
2063 
2064  renderer->DestroyTexture(renderer, texture);
2065  SDL_free(texture);
2066 }
2067 
2068 void
2070 {
2071  CHECK_RENDERER_MAGIC(renderer, );
2072 
2074 
2075  /* Free existing textures for this renderer */
2076  while (renderer->textures) {
2077  SDL_Texture *tex = renderer->textures; (void) tex;
2078  SDL_DestroyTexture(renderer->textures);
2079  SDL_assert(tex != renderer->textures); /* satisfy static analysis. */
2080  }
2081 
2082  if (renderer->window) {
2084  }
2085 
2086  /* It's no longer magical... */
2087  renderer->magic = NULL;
2088 
2089  /* Free the renderer instance */
2090  renderer->DestroyRenderer(renderer);
2091 }
2092 
2093 int SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh)
2094 {
2096 
2097  CHECK_TEXTURE_MAGIC(texture, -1);
2098  renderer = texture->renderer;
2099  if (texture->native) {
2100  return SDL_GL_BindTexture(texture->native, texw, texh);
2101  } else if (renderer && renderer->GL_BindTexture) {
2102  return renderer->GL_BindTexture(renderer, texture, texw, texh);
2103  } else {
2104  return SDL_Unsupported();
2105  }
2106 }
2107 
2109 {
2111 
2112  CHECK_TEXTURE_MAGIC(texture, -1);
2113  renderer = texture->renderer;
2114  if (texture->native) {
2115  return SDL_GL_UnbindTexture(texture->native);
2116  } else if (renderer && renderer->GL_UnbindTexture) {
2117  return renderer->GL_UnbindTexture(renderer, texture);
2118  }
2119 
2120  return SDL_Unsupported();
2121 }
2122 
2123 void *
2125 {
2126  CHECK_RENDERER_MAGIC(renderer, NULL);
2127 
2128  if (renderer->GetMetalLayer) {
2129  return renderer->GetMetalLayer(renderer);
2130  }
2131  return NULL;
2132 }
2133 
2134 void *
2136 {
2137  CHECK_RENDERER_MAGIC(renderer, NULL);
2138 
2139  if (renderer->GetMetalCommandEncoder) {
2140  return renderer->GetMetalCommandEncoder(renderer);
2141  }
2142  return NULL;
2143 }
2144 
2145 static SDL_BlendMode
2147 {
2148  if (blendMode == SDL_BLENDMODE_NONE_FULL) {
2149  return SDL_BLENDMODE_NONE;
2150  }
2151  if (blendMode == SDL_BLENDMODE_BLEND_FULL) {
2152  return SDL_BLENDMODE_BLEND;
2153  }
2154  if (blendMode == SDL_BLENDMODE_ADD_FULL) {
2155  return SDL_BLENDMODE_ADD;
2156  }
2157  if (blendMode == SDL_BLENDMODE_MOD_FULL) {
2158  return SDL_BLENDMODE_MOD;
2159  }
2160  return blendMode;
2161 }
2162 
2163 static SDL_BlendMode
2165 {
2166  if (blendMode == SDL_BLENDMODE_NONE) {
2167  return SDL_BLENDMODE_NONE_FULL;
2168  }
2169  if (blendMode == SDL_BLENDMODE_BLEND) {
2170  return SDL_BLENDMODE_BLEND_FULL;
2171  }
2172  if (blendMode == SDL_BLENDMODE_ADD) {
2173  return SDL_BLENDMODE_ADD_FULL;
2174  }
2175  if (blendMode == SDL_BLENDMODE_MOD) {
2176  return SDL_BLENDMODE_MOD_FULL;
2177  }
2178  return blendMode;
2179 }
2180 
2183  SDL_BlendOperation colorOperation,
2184  SDL_BlendFactor srcAlphaFactor, SDL_BlendFactor dstAlphaFactor,
2185  SDL_BlendOperation alphaOperation)
2186 {
2187  SDL_BlendMode blendMode = SDL_COMPOSE_BLENDMODE(srcColorFactor, dstColorFactor, colorOperation,
2188  srcAlphaFactor, dstAlphaFactor, alphaOperation);
2189  return SDL_GetShortBlendMode(blendMode);
2190 }
2191 
2194 {
2195  blendMode = SDL_GetLongBlendMode(blendMode);
2196  return (SDL_BlendFactor)(((Uint32)blendMode >> 4) & 0xF);
2197 }
2198 
2201 {
2202  blendMode = SDL_GetLongBlendMode(blendMode);
2203  return (SDL_BlendFactor)(((Uint32)blendMode >> 8) & 0xF);
2204 }
2205 
2208 {
2209  blendMode = SDL_GetLongBlendMode(blendMode);
2210  return (SDL_BlendOperation)(((Uint32)blendMode >> 0) & 0xF);
2211 }
2212 
2215 {
2216  blendMode = SDL_GetLongBlendMode(blendMode);
2217  return (SDL_BlendFactor)(((Uint32)blendMode >> 20) & 0xF);
2218 }
2219 
2222 {
2223  blendMode = SDL_GetLongBlendMode(blendMode);
2224  return (SDL_BlendFactor)(((Uint32)blendMode >> 24) & 0xF);
2225 }
2226 
2229 {
2230  blendMode = SDL_GetLongBlendMode(blendMode);
2231  return (SDL_BlendOperation)(((Uint32)blendMode >> 16) & 0xF);
2232 }
2233 
2234 /* vi: set ts=4 sw=4 expandtab: */
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:2193
SDL_BlendFactor
The normalized factor used to multiply pixel components.
Definition: SDL_blendmode.h:75
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:258
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:533
#define SDL_DelEventWatch
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
#define SDL_GetWindowData
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_sysrender.h:98
#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:31
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
#define SDL_UnlockSurface
#define SDL_ceil
static Uint32 GetClosestSupportedFormat(SDL_Renderer *renderer, Uint32 format)
Definition: SDL_render.c:471
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:932
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:1861
#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:154
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:1526
SDL_RendererInfo info
void * SDL_RenderGetMetalCommandEncoder(SDL_Renderer *renderer)
Get the Metal command encoder for the current frame.
Definition: SDL_render.c:2135
int SDL_GetRendererInfo(SDL_Renderer *renderer, SDL_RendererInfo *info)
Get information about a rendering context.
Definition: SDL_render.c:414
SDL_Rect clip_rect_backup
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
#define SDL_ISPIXELFORMAT_INDEXED(format)
Definition: SDL_pixels.h:134
SDL_RenderDriver GLES_RenderDriver
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:40
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
Definition: SDL_sysrender.h:82
SDL_RenderDriver DirectFB_RenderDriver
#define SDL_ConvertSurface
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
SDL_Rect rect
Definition: testrelative.c:27
#define SDL_fabs
SDL_RenderDriver D3D11_RenderDriver
SDL_bool hidden
GLfloat GLfloat GLfloat GLfloat h
SDL_Texture * SDL_GetRenderTarget(SDL_Renderer *renderer)
Get the current render target or NULL for the default render target.
Definition: SDL_render.c:1236
GLfixed GLfixed GLfixed y2
SDL_RenderDriver PSP_RenderDriver
EGLSurface surface
Definition: eglext.h:248
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
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:2221
#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:302
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:1505
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:2207
GLfloat f
SDL_BlendMode SDL_ComposeCustomBlendMode(SDL_BlendFactor srcColorFactor, SDL_BlendFactor dstColorFactor, SDL_BlendOperation colorOperation, SDL_BlendFactor srcAlphaFactor, SDL_BlendFactor dstAlphaFactor, SDL_BlendOperation alphaOperation)
Create a custom blend mode, which may or may not be supported by a given renderer.
Definition: SDL_render.c:2182
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:128
SDL_Rect locked_rect
Definition: SDL_sysrender.h:67
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
#define SDL_CreateWindow
static int SDL_UpdateTextureNative(SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_render.c:855
int SDL_RenderDrawPoint(SDL_Renderer *renderer, int x, int y)
Draw a point on the current rendering target.
Definition: SDL_render.c:1559
#define SDL_AllocFormat
#define SDL_WINDOWPOS_UNDEFINED
Definition: SDL_video.h:130
SDL_RenderDriver GL_RenderDriver
#define SDL_ISPIXELFORMAT_ALPHA(format)
Definition: SDL_pixels.h:154
SDL_Rect clip_rect
static int RenderDrawPointsWithRects(SDL_Renderer *renderer, const SDL_Point *points, int count)
Definition: SDL_render.c:1569
uint32_t Uint32
Definition: SDL_stdinc.h:181
#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:1398
#define SDL_strcasecmp
void SDL_RenderPresent(SDL_Renderer *renderer)
Update the screen with rendering performed.
Definition: SDL_render.c:2022
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:1985
#define SDL_IntersectRect
SDL_Texture * textures
#define SDL_floor
int max_texture_height
Definition: SDL_render.h:85
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
Definition: SDL_blendmode.h:62
static char texture_magic
Definition: SDL_render.c:106
SDL_Window * window
void SDL_RenderGetLogicalSize(SDL_Renderer *renderer, int *w, int *h)
Get device independent resolution for rendering.
Definition: SDL_render.c:1367
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:423
#define SDL_max(x, y)
Definition: SDL_stdinc.h:407
GLfixed GLfixed x2
static int SDL_LockTextureYUV(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_render.c:1044
int(* RenderClear)(SDL_Renderer *renderer)
GLfloat GLfloat GLfloat alpha
GLuint GLint GLboolean GLint GLenum access
static int RenderDrawLinesWithRects(SDL_Renderer *renderer, const SDL_Point *points, int count)
Definition: SDL_render.c:1649
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:1804
void(* DestroyRenderer)(SDL_Renderer *renderer)
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
GLfixed GLfixed GLint GLint GLfixed points
void * SDL_RenderGetMetalLayer(SDL_Renderer *renderer)
Get the CAMetalLayer associated with the given Metal renderer.
Definition: SDL_render.c:2124
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:88
int SDL_QueryTexture(SDL_Texture *texture, Uint32 *format, int *access, int *w, int *h)
Query the attributes of a texture.
Definition: SDL_render.c:679
#define SDL_GetHintBoolean
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:1115
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:798
#define SDL_SetWindowData
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
SDL_WindowEvent window
Definition: SDL_events.h:529
static SDL_BlendMode SDL_GetShortBlendMode(SDL_BlendMode blendMode)
Definition: SDL_render.c:2146
SDL_Renderer * SDL_CreateSoftwareRenderer(SDL_Surface *surface)
Create a 2D software rendering context for a surface.
Definition: SDL_render.c:386
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_sysrender.h:90
int SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_yuv_sw.c:139
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:93
#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:777
SDL_RenderDriver METAL_RenderDriver
int(* SetTextureColorMod)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:84
SDL_RenderDriver GLES2_RenderDriver
SDL_Texture * next
Definition: SDL_sysrender.h:72
GLenum GLenum GLuint texture
#define CHECK_RENDERER_MAGIC(renderer, retval)
Definition: SDL_render.c:35
SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:2228
void SDL_DestroyTexture(SDL_Texture *texture)
Destroy the specified texture.
Definition: SDL_render.c:2034
SDL_Texture * prev
Definition: SDL_sysrender.h:71
GLfloat minY
Definition: gl2ext.h:446
void SDL_DestroyRenderer(SDL_Renderer *renderer)
Destroy the rendering context for a window and free associated textures.
Definition: SDL_render.c:2069
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:1776
SDL_Texture * target
int y
Definition: SDL_rect.h:51
void * pixels
Definition: SDL_surface.h:75
#define SDL_GetColorKey
#define SDL_FreeSurface
static SDL_Renderer * renderer
int SDL_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count)
Draw multiple points on the current rendering target.
Definition: SDL_render.c:1595
uint8_t Uint8
Definition: SDL_stdinc.h:157
#define SDL_free
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:354
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:1136
SDL_BlendMode blendMode
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:1063
int SDL_GetRenderDrawBlendMode(SDL_Renderer *renderer, SDL_BlendMode *blendMode)
Get the blend mode used for drawing operations.
Definition: SDL_render.c:1538
SDL_Texture * SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *surface)
Create a texture from an existing surface.
Definition: SDL_render.c:591
#define SDL_BLENDMODE_BLEND_FULL
Definition: SDL_render.c:63
#define SDL_FreeFormat
int SDL_RenderSetIntegerScale(SDL_Renderer *renderer, SDL_bool enable)
Set whether to force integer scales for resolution-independent rendering.
Definition: SDL_render.c:1380
GLfloat GLfloat GLfloat GLfloat maxX
Definition: gl2ext.h:446
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
GLubyte GLubyte GLubyte GLubyte w
void *(* GetMetalLayer)(SDL_Renderer *renderer)
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_Renderer *(* CreateRenderer)(SDL_Window *window, Uint32 flags)
#define SDL_BLENDMODE_MOD_FULL
Definition: SDL_render.c:71
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
int SDL_RenderDrawRect(SDL_Renderer *renderer, const SDL_Rect *rect)
Draw a rectangle on the current rendering target.
Definition: SDL_render.c:1747
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
int SDL_GetNumRenderDrivers(void)
Get the number of 2D rendering drivers available for the current display.
Definition: SDL_render.c:111
void SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture *swdata)
Definition: SDL_yuv_sw.c:404
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:983
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* UpdateViewport)(SDL_Renderer *renderer)
SDL_RenderDriver D3D_RenderDriver
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
#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:725
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:2093
SDL_bool SDL_RenderGetIntegerScale(SDL_Renderer *renderer)
Get whether integer scales are forced for resolution-independent rendering.
Definition: SDL_render.c:1390
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:1156
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
#define SDL_BLENDMODE_NONE_FULL
Definition: SDL_render.c:59
GLuint index
static int UpdateLogicalSize(SDL_Renderer *renderer)
Definition: SDL_render.c:1242
#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:809
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
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:1469
int SDL_SetTextureAlphaMod(SDL_Texture *texture, Uint8 alpha)
Set an additional alpha value used in render copy operations.
Definition: SDL_render.c:743
void SDL_RenderGetClipRect(SDL_Renderer *renderer, SDL_Rect *rect)
Get the clip rectangle for the current target.
Definition: SDL_render.c:1449
#define SDL_assert(condition)
Definition: SDL_assert.h:169
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:896
#define SDL_HINT_RENDER_LOGICAL_SIZE_MODE
A variable controlling the scaling policy for SDL_RenderSetLogicalSize.
Definition: SDL_hints.h:131
int SDL_RenderClear(SDL_Renderer *renderer)
Clear the current rendering target with the drawing color.
Definition: SDL_render.c:1547
SDL_bool SDL_RenderIsClipEnabled(SDL_Renderer *renderer)
Get whether clipping is enabled on the given renderer.
Definition: SDL_render.c:1462
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
Definition: SDL_stdinc.h:139
#define SDL_GetCurrentVideoDriver
GLfloat GLfloat GLfloat GLfloat GLfloat maxY
Definition: gl2ext.h:446
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:2214
GLboolean enable
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:76
#define SDL_WINDOWRENDERDATA
Definition: SDL_render.c:33
GLbitfield flags
static SDL_bool IsSupportedFormat(SDL_Renderer *renderer, Uint32 format)
Definition: SDL_render.c:458
SDL_Renderer * renderer
Definition: SDL_sysrender.h:60
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
SDL_Renderer * SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags)
Create a 2D rendering context for a window.
Definition: SDL_render.c:278
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)
#define SDL_calloc
#define SDL_GetSurfaceColorMod
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
#define CHECK_TEXTURE_MAGIC(texture, retval)
Definition: SDL_render.c:42
#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:247
#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:1705
int h
Definition: SDL_rect.h:67
int(* SetTextureAlphaMod)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:86
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
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:1821
The type used to identify a window.
Definition: SDL_sysvideo.h:73
#define SDL_GetWindowPixelFormat
SDL_Renderer * SDL_GetRenderer(SDL_Window *window)
Get the renderer associated with a window.
Definition: SDL_render.c:408
SDL_Rect viewport
Definition: testviewport.c:28
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:2200
GLdouble n
void SDL_RenderGetViewport(SDL_Renderer *renderer, SDL_Rect *rect)
Get the drawing area for the current target.
Definition: SDL_render.c:1418
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:334
#define SDL_HINT_RENDER_DRIVER
A variable specifying which render driver to use.
Definition: SDL_hints.h:85
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:1479
int window_h
Definition: testoverlay2.c:144
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:700
GLfloat angle
SDL_MouseButtonEvent button
Definition: SDL_events.h:534
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:1431
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:1914
Uint32 format
Definition: SDL_sysrender.h:52
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
static char renderer_magic
Definition: SDL_render.c:105
General event structure.
Definition: SDL_events.h:525
#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:1492
#define SDL_BLENDMODE_ADD_FULL
Definition: SDL_render.c:67
#define SDL_ConvertPixels
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:83
SDL_Texture * native
Definition: SDL_sysrender.h:63
void(* RenderPresent)(SDL_Renderer *renderer)
#define SDL_ISPIXELFORMAT_FOURCC(format)
Definition: SDL_pixels.h:167
EGLSurface EGLint * rects
Definition: eglext.h:282
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:355
static SDL_BlendMode SDL_GetLongBlendMode(SDL_BlendMode blendMode)
Definition: SDL_render.c:2164
SDL_Rect viewport_backup
int SDL_RenderSetLogicalSize(SDL_Renderer *renderer, int w, int h)
Set device independent resolution for rendering.
Definition: SDL_render.c:1347
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:1165
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:1637
int(* UpdateClipRect)(SDL_Renderer *renderer)
#define SDLCALL
Definition: SDL_internal.h:45
GLboolean GLboolean g
static void SDL_UnlockTextureYUV(SDL_Texture *texture)
Definition: SDL_render.c:1094
GLboolean GLboolean GLboolean b
SDL_bool clipping_enabled_backup
int y
Definition: SDL_rect.h:66
#define SDL_Unsupported()
Definition: SDL_error.h:53
int window_w
Definition: testoverlay2.c:143
SDL_FPoint dpi_scale
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:497
int SDL_GetTextureAlphaMod(SDL_Texture *texture, Uint8 *alpha)
Get the additional alpha value used in render copy operations.
Definition: SDL_render.c:766
SDL_bool integer_scale
SDL_bool clipping_enabled
static int SDL_RendererEventWatch(void *userdata, SDL_Event *event)
Definition: SDL_render.c:136
#define SDL_COMPOSE_BLENDMODE(srcColorFactor, dstColorFactor, colorOperation, srcAlphaFactor, dstAlphaFactor, alphaOperation)
Definition: SDL_render.c:50
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:2108
static int SDL_LockTextureNative(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_render.c:1051
Uint32 type
Definition: SDL_events.h:527
void *(* GetMetalCommandEncoder)(SDL_Renderer *renderer)
int SDL_GetRenderDriverInfo(int index, SDL_RendererInfo *info)
Get information about a specific 2D rendering driver for the current display.
Definition: SDL_render.c:121
static SDL_bool IsSupportedBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode)
Definition: SDL_render.c:441