SDL  2.0
SDL_render.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 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_hints.h"
26 #include "SDL_render.h"
27 #include "SDL_sysrender.h"
29 #include "../video/SDL_pixels_c.h"
30 
31 #if defined(__ANDROID__)
32 # include "../core/android/SDL_android.h"
33 #endif
34 
35 #define SDL_WINDOWRENDERDATA "_SDL_WindowRenderData"
36 
37 #define CHECK_RENDERER_MAGIC(renderer, retval) \
38  SDL_assert(renderer && renderer->magic == &renderer_magic); \
39  if (!renderer || renderer->magic != &renderer_magic) { \
40  SDL_SetError("Invalid renderer"); \
41  return retval; \
42  }
43 
44 #define CHECK_TEXTURE_MAGIC(texture, retval) \
45  SDL_assert(texture && texture->magic == &texture_magic); \
46  if (!texture || texture->magic != &texture_magic) { \
47  SDL_SetError("Invalid texture"); \
48  return retval; \
49  }
50 
51 /* Predefined blend modes */
52 #define SDL_COMPOSE_BLENDMODE(srcColorFactor, dstColorFactor, colorOperation, \
53  srcAlphaFactor, dstAlphaFactor, alphaOperation) \
54  (SDL_BlendMode)(((Uint32)colorOperation << 0) | \
55  ((Uint32)srcColorFactor << 4) | \
56  ((Uint32)dstColorFactor << 8) | \
57  ((Uint32)alphaOperation << 16) | \
58  ((Uint32)srcAlphaFactor << 20) | \
59  ((Uint32)dstAlphaFactor << 24))
60 
61 #define SDL_BLENDMODE_NONE_FULL \
62  SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ZERO, SDL_BLENDOPERATION_ADD, \
63  SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ZERO, SDL_BLENDOPERATION_ADD)
64 
65 #define SDL_BLENDMODE_BLEND_FULL \
66  SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, \
67  SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD)
68 
69 #define SDL_BLENDMODE_ADD_FULL \
70  SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD, \
71  SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD)
72 
73 #define SDL_BLENDMODE_MOD_FULL \
74  SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_SRC_COLOR, SDL_BLENDOPERATION_ADD, \
75  SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD)
76 
77 #define SDL_BLENDMODE_MUL_FULL \
78  SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_DST_COLOR, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, \
79  SDL_BLENDFACTOR_DST_ALPHA, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD)
80 
81 #if !SDL_RENDER_DISABLED
82 static const SDL_RenderDriver *render_drivers[] = {
83 #if SDL_VIDEO_RENDER_D3D
85 #endif
86 #if SDL_VIDEO_RENDER_D3D11
88 #endif
89 #if SDL_VIDEO_RENDER_METAL
91 #endif
92 #if SDL_VIDEO_RENDER_OGL
94 #endif
95 #if SDL_VIDEO_RENDER_OGL_ES2
97 #endif
98 #if SDL_VIDEO_RENDER_OGL_ES
100 #endif
101 #if SDL_VIDEO_RENDER_DIRECTFB
103 #endif
104 #if SDL_VIDEO_RENDER_PSP
106 #endif
107 #if SDL_VIDEO_RENDER_SW
109 #endif
110 };
111 #endif /* !SDL_RENDER_DISABLED */
112 
113 static char renderer_magic;
114 static char texture_magic;
115 
116 static SDL_INLINE void
118 {
119 #if 0
120  unsigned int i = 1;
121  SDL_Log("Render commands to flush:");
122  while (cmd) {
123  switch (cmd->command) {
124  case SDL_RENDERCMD_NO_OP:
125  SDL_Log(" %u. no-op", i++);
126  break;
127 
129  SDL_Log(" %u. set viewport (first=%u, rect={(%d, %d), %dx%d})", i++,
130  (unsigned int) cmd->data.viewport.first,
131  cmd->data.viewport.rect.x, cmd->data.viewport.rect.y,
132  cmd->data.viewport.rect.w, cmd->data.viewport.rect.h);
133  break;
134 
136  SDL_Log(" %u. set cliprect (enabled=%s, rect={(%d, %d), %dx%d})", i++,
137  cmd->data.cliprect.enabled ? "true" : "false",
138  cmd->data.cliprect.rect.x, cmd->data.cliprect.rect.y,
139  cmd->data.cliprect.rect.w, cmd->data.cliprect.rect.h);
140  break;
141 
143  SDL_Log(" %u. set draw color (first=%u, r=%d, g=%d, b=%d, a=%d)", i++,
144  (unsigned int) cmd->data.color.first,
145  (int) cmd->data.color.r, (int) cmd->data.color.g,
146  (int) cmd->data.color.b, (int) cmd->data.color.a);
147  break;
148 
149  case SDL_RENDERCMD_CLEAR:
150  SDL_Log(" %u. clear (first=%u, r=%d, g=%d, b=%d, a=%d)", i++,
151  (unsigned int) cmd->data.color.first,
152  (int) cmd->data.color.r, (int) cmd->data.color.g,
153  (int) cmd->data.color.b, (int) cmd->data.color.a);
154  break;
155 
157  SDL_Log(" %u. draw points (first=%u, count=%u, r=%d, g=%d, b=%d, a=%d, blend=%d)", i++,
158  (unsigned int) cmd->data.draw.first,
159  (unsigned int) cmd->data.draw.count,
160  (int) cmd->data.draw.r, (int) cmd->data.draw.g,
161  (int) cmd->data.draw.b, (int) cmd->data.draw.a,
162  (int) cmd->data.draw.blend);
163  break;
164 
166  SDL_Log(" %u. draw lines (first=%u, count=%u, r=%d, g=%d, b=%d, a=%d, blend=%d)", i++,
167  (unsigned int) cmd->data.draw.first,
168  (unsigned int) cmd->data.draw.count,
169  (int) cmd->data.draw.r, (int) cmd->data.draw.g,
170  (int) cmd->data.draw.b, (int) cmd->data.draw.a,
171  (int) cmd->data.draw.blend);
172  break;
173 
175  SDL_Log(" %u. fill rects (first=%u, count=%u, r=%d, g=%d, b=%d, a=%d, blend=%d)", i++,
176  (unsigned int) cmd->data.draw.first,
177  (unsigned int) cmd->data.draw.count,
178  (int) cmd->data.draw.r, (int) cmd->data.draw.g,
179  (int) cmd->data.draw.b, (int) cmd->data.draw.a,
180  (int) cmd->data.draw.blend);
181  break;
182 
183  case SDL_RENDERCMD_COPY:
184  SDL_Log(" %u. copy (first=%u, count=%u, r=%d, g=%d, b=%d, a=%d, blend=%d, tex=%p)", i++,
185  (unsigned int) cmd->data.draw.first,
186  (unsigned int) cmd->data.draw.count,
187  (int) cmd->data.draw.r, (int) cmd->data.draw.g,
188  (int) cmd->data.draw.b, (int) cmd->data.draw.a,
189  (int) cmd->data.draw.blend, cmd->data.draw.texture);
190  break;
191 
192 
194  SDL_Log(" %u. copyex (first=%u, count=%u, r=%d, g=%d, b=%d, a=%d, blend=%d, tex=%p)", i++,
195  (unsigned int) cmd->data.draw.first,
196  (unsigned int) cmd->data.draw.count,
197  (int) cmd->data.draw.r, (int) cmd->data.draw.g,
198  (int) cmd->data.draw.b, (int) cmd->data.draw.a,
199  (int) cmd->data.draw.blend, cmd->data.draw.texture);
200  break;
201  }
202  cmd = cmd->next;
203  }
204 #endif
205 }
206 
207 static int
209 {
210  int retval;
211 
213 
214  if (renderer->render_commands == NULL) { /* nothing to do! */
216  return 0;
217  }
218 
220 
222 
223  /* Move the whole render command queue to the unused pool so we can reuse them next time. */
229  }
235  return retval;
236 }
237 
238 static int
240 {
241  SDL_Renderer *renderer = texture->renderer;
242  if (texture->last_command_generation == renderer->render_command_generation) {
243  /* the current command queue depends on this texture, flush the queue now before it changes */
245  }
246  return 0;
247 }
248 
249 static SDL_INLINE int
251 {
253 }
254 
255 int
257 {
259 }
260 
261 void *
262 SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset)
263 {
264  const size_t needed = renderer->vertex_data_used + numbytes + alignment;
265  size_t current_offset = renderer->vertex_data_used;
266 
267  size_t aligner = (alignment && ((current_offset & (alignment - 1)) != 0)) ? (alignment - (current_offset & (alignment - 1))) : 0;
268  size_t aligned = current_offset + aligner;
269 
270  if (renderer->vertex_data_allocation < needed) {
271  const size_t current_allocation = renderer->vertex_data ? renderer->vertex_data_allocation : 1024;
272  size_t newsize = current_allocation * 2;
273  void *ptr;
274  while (newsize < needed) {
275  newsize *= 2;
276  }
277  ptr = SDL_realloc(renderer->vertex_data, newsize);
278  if (ptr == NULL) {
279  SDL_OutOfMemory();
280  return NULL;
281  }
283  renderer->vertex_data_allocation = newsize;
284  }
285 
286  if (offset) {
287  *offset = aligned;
288  }
289 
290  renderer->vertex_data_used += aligner + numbytes;
291 
292  return ((Uint8 *) renderer->vertex_data) + aligned;
293 }
294 
295 static SDL_RenderCommand *
297 {
299 
300  /* !!! FIXME: are there threading limitations in SDL's render API? If not, we need to mutex this. */
302  if (retval != NULL) {
304  retval->next = NULL;
305  } else {
306  retval = SDL_calloc(1, sizeof (*retval));
307  if (!retval) {
308  SDL_OutOfMemory();
309  return NULL;
310  }
311  }
312 
316  } else {
318  }
320 
321  return retval;
322 }
323 
324 static int
326 {
327  int retval = 0;
330  retval = -1;
331  if (cmd != NULL) {
333  cmd->data.viewport.first = 0; /* render backend will fill this in. */
334  SDL_memcpy(&cmd->data.viewport.rect, &renderer->viewport, sizeof (renderer->viewport));
336  if (retval < 0) {
338  } else {
341  }
342  }
343  }
344  return retval;
345 }
346 
347 static int
349 {
350  int retval = 0;
351  if ((!renderer->cliprect_queued) ||
355  if (cmd == NULL) {
356  retval = -1;
357  } else {
359  cmd->data.cliprect.enabled = renderer->clipping_enabled;
360  SDL_memcpy(&cmd->data.cliprect.rect, &renderer->clip_rect, sizeof (cmd->data.cliprect.rect));
364  }
365  }
366  return retval;
367 }
368 
369 static int
371 {
372  const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
373  int retval = 0;
374 
377  retval = -1;
378 
379  if (cmd != NULL) {
381  cmd->data.color.first = 0; /* render backend will fill this in. */
382  cmd->data.color.r = r;
383  cmd->data.color.g = g;
384  cmd->data.color.b = b;
385  cmd->data.color.a = a;
387  if (retval < 0) {
389  } else {
392  }
393  }
394  }
395  return retval;
396 }
397 
398 static int
400 {
402  if (cmd == NULL) {
403  return -1;
404  }
405 
407  cmd->data.color.first = 0;
408  cmd->data.color.r = renderer->r;
409  cmd->data.color.g = renderer->g;
410  cmd->data.color.b = renderer->b;
411  cmd->data.color.a = renderer->a;
412  return 0;
413 }
414 
415 static int
417 {
419 
420  /* Set the viewport and clip rect directly before draws, so the backends
421  * don't have to worry about that state not being valid at draw time. */
422  if (retval == 0 && !renderer->viewport_queued) {
424  }
425  if (retval == 0 && !renderer->cliprect_queued) {
427  }
428  return retval;
429 }
430 
431 static SDL_RenderCommand *
433 {
434  /* !!! FIXME: drop this draw if viewport w or h is zero. */
435  SDL_RenderCommand *cmd = NULL;
438  if (cmd != NULL) {
439  cmd->command = cmdtype;
440  cmd->data.draw.first = 0; /* render backend will fill this in. */
441  cmd->data.draw.count = 0; /* render backend will fill this in. */
442  cmd->data.draw.r = renderer->r;
443  cmd->data.draw.g = renderer->g;
444  cmd->data.draw.b = renderer->b;
445  cmd->data.draw.a = renderer->a;
446  cmd->data.draw.blend = renderer->blendMode;
447  cmd->data.draw.texture = NULL; /* no texture. */
448  }
449  }
450  return cmd;
451 }
452 
453 static int
455 {
457  int retval = -1;
458  if (cmd != NULL) {
460  if (retval < 0) {
462  }
463  }
464  return retval;
465 }
466 
467 static int
469 {
471  int retval = -1;
472  if (cmd != NULL) {
474  if (retval < 0) {
476  }
477  }
478  return retval;
479 }
480 
481 static int
483 {
485  int retval = -1;
486  if (cmd != NULL) {
488  if (retval < 0) {
490  }
491  }
492  return retval;
493 }
494 
495 static SDL_RenderCommand *
497 {
498  /* !!! FIXME: drop this draw if viewport w or h is zero. */
499  SDL_RenderCommand *cmd = NULL;
500  if (PrepQueueCmdDraw(renderer, texture->r, texture->g, texture->b, texture->a) == 0) {
502  if (cmd != NULL) {
503  cmd->command = cmdtype;
504  cmd->data.draw.first = 0; /* render backend will fill this in. */
505  cmd->data.draw.count = 0; /* render backend will fill this in. */
506  cmd->data.draw.r = texture->r;
507  cmd->data.draw.g = texture->g;
508  cmd->data.draw.b = texture->b;
509  cmd->data.draw.a = texture->a;
510  cmd->data.draw.blend = texture->blendMode;
511  cmd->data.draw.texture = texture;
512  }
513  }
514  return cmd;
515 }
516 
517 static int
519 {
521  int retval = -1;
522  if (cmd != NULL) {
523  retval = renderer->QueueCopy(renderer, cmd, texture, srcrect, dstrect);
524  if (retval < 0) {
526  }
527  }
528  return retval;
529 }
530 
531 static int
533  const SDL_Rect * srcquad, const SDL_FRect * dstrect,
534  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
535 {
537  int retval = -1;
538  SDL_assert(renderer->QueueCopyEx != NULL); /* should have caught at higher level. */
539  if (cmd != NULL) {
540  retval = renderer->QueueCopyEx(renderer, cmd, texture, srcquad, dstrect, angle, center, flip);
541  if (retval < 0) {
543  }
544  }
545  return retval;
546 }
547 
548 
550 
551 int
553 {
554 #if !SDL_RENDER_DISABLED
556 #else
557  return 0;
558 #endif
559 }
560 
561 int
563 {
564 #if !SDL_RENDER_DISABLED
566  return SDL_SetError("index must be in the range of 0 - %d",
568  }
569  *info = render_drivers[index]->info;
570  return 0;
571 #else
572  return SDL_SetError("SDL not built with rendering support");
573 #endif
574 }
575 
576 static void GetWindowViewportValues(SDL_Renderer *renderer, int *logical_w, int *logical_h, SDL_Rect *viewport, SDL_FPoint *scale)
577 {
584 }
585 
586 static int SDLCALL
588 {
589  SDL_Renderer *renderer = (SDL_Renderer *)userdata;
590 
591  if (event->type == SDL_WINDOWEVENT) {
592  SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
593  if (window == renderer->window) {
594  if (renderer->WindowEvent) {
596  }
597 
598  if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
599  /* Make sure we're operating on the default render target */
600  SDL_Texture *saved_target = SDL_GetRenderTarget(renderer);
601  if (saved_target) {
603  }
604 
605  if (renderer->logical_w) {
607  } else {
608  /* Window was resized, reset viewport */
609  int w, h;
610 
611  if (renderer->GetOutputSize) {
613  } else {
615  }
616 
617  if (renderer->target) {
622  } else {
623  renderer->viewport.x = 0;
624  renderer->viewport.y = 0;
625  renderer->viewport.w = w;
626  renderer->viewport.h = h;
629  }
630  }
631 
632  if (saved_target) {
633  SDL_SetRenderTarget(renderer, saved_target);
634  }
635  } else if (event->window.event == SDL_WINDOWEVENT_HIDDEN) {
637  } else if (event->window.event == SDL_WINDOWEVENT_SHOWN) {
640  }
641  } else if (event->window.event == SDL_WINDOWEVENT_MINIMIZED) {
643  } else if (event->window.event == SDL_WINDOWEVENT_RESTORED ||
644  event->window.event == SDL_WINDOWEVENT_MAXIMIZED) {
647  }
648  }
649  }
650  } else if (event->type == SDL_MOUSEMOTION) {
651  SDL_Window *window = SDL_GetWindowFromID(event->motion.windowID);
652  if (window == renderer->window) {
653  int logical_w, logical_h;
656  GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale);
657  if (logical_w) {
658  event->motion.x -= (int)(viewport.x * renderer->dpi_scale.x);
659  event->motion.y -= (int)(viewport.y * renderer->dpi_scale.y);
660  event->motion.x = (int)(event->motion.x / (scale.x * renderer->dpi_scale.x));
661  event->motion.y = (int)(event->motion.y / (scale.y * renderer->dpi_scale.y));
662  if (event->motion.xrel != 0 && renderer->relative_scaling) {
663  float rel = renderer->xrel + event->motion.xrel / (scale.x * renderer->dpi_scale.x);
664  float trunc = SDL_truncf(rel);
665  renderer->xrel = rel - trunc;
666  event->motion.xrel = (Sint32) trunc;
667  }
668  if (event->motion.yrel != 0 && renderer->relative_scaling) {
669  float rel = renderer->yrel + event->motion.yrel / (scale.y * renderer->dpi_scale.y);
670  float trunc = SDL_truncf(rel);
671  renderer->yrel = rel - trunc;
672  event->motion.yrel = (Sint32) trunc;
673  }
674  }
675  }
676  } else if (event->type == SDL_MOUSEBUTTONDOWN ||
677  event->type == SDL_MOUSEBUTTONUP) {
678  SDL_Window *window = SDL_GetWindowFromID(event->button.windowID);
679  if (window == renderer->window) {
680  int logical_w, logical_h;
683  GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale);
684  if (logical_w) {
685  event->button.x -= (int)(viewport.x * renderer->dpi_scale.x);
686  event->button.y -= (int)(viewport.y * renderer->dpi_scale.y);
687  event->button.x = (int)(event->button.x / (scale.x * renderer->dpi_scale.x));
688  event->button.y = (int)(event->button.y / (scale.y * renderer->dpi_scale.y));
689  }
690  }
691  } else if (event->type == SDL_FINGERDOWN ||
692  event->type == SDL_FINGERUP ||
693  event->type == SDL_FINGERMOTION) {
694  int logical_w, logical_h;
695  float physical_w, physical_h;
698  GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale);
699 
700  /* !!! FIXME: we probably should drop events that are outside of the
701  !!! FIXME: viewport, but we can't do that from an event watcher,
702  !!! FIXME: and we would have to track if a touch happened outside
703  !!! FIXME: the viewport and then slid into it to insert extra
704  !!! FIXME: events, which is a mess, so for now we just clamp these
705  !!! FIXME: events to the edge. */
706 
707  if (renderer->GetOutputSize) {
708  int w, h;
710  physical_w = (float) w;
711  physical_h = (float) h;
712  } else {
713  int w, h;
715  physical_w = ((float) w) * renderer->dpi_scale.x;
716  physical_h = ((float) h) * renderer->dpi_scale.y;
717  }
718 
719  if (physical_w == 0.0f) { /* nowhere for the touch to go, avoid division by zero and put it dead center. */
720  event->tfinger.x = 0.5f;
721  } else {
722  const float normalized_viewport_x = ((float) viewport.x) / physical_w;
723  const float normalized_viewport_w = ((float) viewport.w) / physical_w;
724  if (event->tfinger.x <= normalized_viewport_x) {
725  event->tfinger.x = 0.0f; /* to the left of the viewport, clamp to the edge. */
726  } else if (event->tfinger.x >= (normalized_viewport_x + normalized_viewport_w)) {
727  event->tfinger.x = 1.0f; /* to the right of the viewport, clamp to the edge. */
728  } else {
729  event->tfinger.x = (event->tfinger.x - normalized_viewport_x) / normalized_viewport_w;
730  }
731  }
732 
733  if (physical_h == 0.0f) { /* nowhere for the touch to go, avoid division by zero and put it dead center. */
734  event->tfinger.y = 0.5f;
735  } else {
736  const float normalized_viewport_y = ((float) viewport.y) / physical_h;
737  const float normalized_viewport_h = ((float) viewport.h) / physical_h;
738  if (event->tfinger.y <= normalized_viewport_y) {
739  event->tfinger.y = 0.0f; /* to the left of the viewport, clamp to the edge. */
740  } else if (event->tfinger.y >= (normalized_viewport_y + normalized_viewport_h)) {
741  event->tfinger.y = 1.0f; /* to the right of the viewport, clamp to the edge. */
742  } else {
743  event->tfinger.y = (event->tfinger.y - normalized_viewport_y) / normalized_viewport_h;
744  }
745  }
746  }
747 
748  return 0;
749 }
750 
751 int
754 {
757  width, height, window_flags);
758  if (!*window) {
759  *renderer = NULL;
760  return -1;
761  }
762 
763  *renderer = SDL_CreateRenderer(*window, -1, 0);
764  if (!*renderer) {
765  return -1;
766  }
767 
768  return 0;
769 }
770 
771 static SDL_INLINE
773 {
774  /* all of these functions are required to be implemented, even as no-ops, so we don't
775  have to check that they aren't NULL over and over. */
783 }
784 
785 SDL_Renderer *
787 {
788 #if !SDL_RENDER_DISABLED
790  int n = SDL_GetNumRenderDrivers();
791  SDL_bool batching = SDL_TRUE;
792  const char *hint;
793 
794 #if defined(__ANDROID__)
796 #endif
797 
798  if (!window) {
799  SDL_SetError("Invalid window");
800  goto error;
801  }
802 
803  if (SDL_GetRenderer(window)) {
804  SDL_SetError("Renderer already associated with window");
805  goto error;
806  }
807 
811  } else {
813  }
814  }
815 
816  if (index < 0) {
818  if (hint) {
819  for (index = 0; index < n; ++index) {
820  const SDL_RenderDriver *driver = render_drivers[index];
821 
822  if (SDL_strcasecmp(hint, driver->info.name) == 0) {
823  /* Create a new renderer instance */
824  renderer = driver->CreateRenderer(window, flags);
825  if (renderer) {
826  batching = SDL_FALSE;
827  }
828  break;
829  }
830  }
831  }
832 
833  if (!renderer) {
834  for (index = 0; index < n; ++index) {
835  const SDL_RenderDriver *driver = render_drivers[index];
836 
837  if ((driver->info.flags & flags) == flags) {
838  /* Create a new renderer instance */
839  renderer = driver->CreateRenderer(window, flags);
840  if (renderer) {
841  /* Yay, we got one! */
842  break;
843  }
844  }
845  }
846  }
847  if (index == n) {
848  SDL_SetError("Couldn't find matching render driver");
849  goto error;
850  }
851  } else {
852  if (index >= SDL_GetNumRenderDrivers()) {
853  SDL_SetError("index must be -1 or in the range of 0 - %d",
855  goto error;
856  }
857  /* Create a new renderer instance */
859  batching = SDL_FALSE;
860  }
861 
862  if (!renderer) {
863  goto error;
864  }
865 
867 
868  /* let app/user override batching decisions. */
869  if (renderer->always_batch) {
870  batching = SDL_TRUE;
873  }
874 
875  renderer->batching = batching;
879  renderer->scale.x = 1.0f;
880  renderer->scale.y = 1.0f;
881  renderer->dpi_scale.x = 1.0f;
882  renderer->dpi_scale.y = 1.0f;
883 
884  /* new textures start at zero, so we start at 1 so first render doesn't flush by accident. */
886 
887  if (window && renderer->GetOutputSize) {
888  int window_w, window_h;
889  int output_w, output_h;
890  if (renderer->GetOutputSize(renderer, &output_w, &output_h) == 0) {
892  renderer->dpi_scale.x = (float)window_w / output_w;
893  renderer->dpi_scale.y = (float)window_h / output_h;
894  }
895  }
896 
898 
901  } else {
903  }
904 
906 
908 
910 
912  "Created renderer: %s", renderer->info.name);
913 
914 #if defined(__ANDROID__)
916 #endif
917  return renderer;
918 
919 error:
920 
921 #if defined(__ANDROID__)
923 #endif
924  return NULL;
925 
926 #else
927  SDL_SetError("SDL not built with rendering support");
928  return NULL;
929 #endif
930 }
931 
932 SDL_Renderer *
934 {
935 #if !SDL_RENDER_DISABLED && SDL_VIDEO_RENDER_SW
937 
939 
940  if (renderer) {
944  renderer->scale.x = 1.0f;
945  renderer->scale.y = 1.0f;
946 
947  /* new textures start at zero, so we start at 1 so first render doesn't flush by accident. */
949 
951  }
952  return renderer;
953 #else
954  SDL_SetError("SDL not built with rendering support");
955  return NULL;
956 #endif /* !SDL_RENDER_DISABLED */
957 }
958 
959 SDL_Renderer *
961 {
963 }
964 
965 int
967 {
969 
970  *info = renderer->info;
971  return 0;
972 }
973 
974 int
976 {
978 
979  if (renderer->target) {
980  return SDL_QueryTexture(renderer->target, NULL, NULL, w, h);
981  } else if (renderer->GetOutputSize) {
982  return renderer->GetOutputSize(renderer, w, h);
983  } else if (renderer->window) {
985  return 0;
986  } else {
987  SDL_assert(0 && "This should never happen");
988  return SDL_SetError("Renderer doesn't support querying output size");
989  }
990 }
991 
992 static SDL_bool
994 {
995  switch (blendMode)
996  {
997  /* These are required to be supported by all renderers */
998  case SDL_BLENDMODE_NONE:
999  case SDL_BLENDMODE_BLEND:
1000  case SDL_BLENDMODE_ADD:
1001  case SDL_BLENDMODE_MOD:
1002  case SDL_BLENDMODE_MUL:
1003  return SDL_TRUE;
1004 
1005  default:
1007  }
1008 }
1009 
1010 static SDL_bool
1012 {
1013  Uint32 i;
1014 
1015  for (i = 0; i < renderer->info.num_texture_formats; ++i) {
1016  if (renderer->info.texture_formats[i] == format) {
1017  return SDL_TRUE;
1018  }
1019  }
1020  return SDL_FALSE;
1021 }
1022 
1023 static Uint32
1025 {
1026  Uint32 i;
1027 
1029  /* Look for an exact match */
1030  for (i = 0; i < renderer->info.num_texture_formats; ++i) {
1031  if (renderer->info.texture_formats[i] == format) {
1032  return renderer->info.texture_formats[i];
1033  }
1034  }
1035  } else {
1037 
1038  /* We just want to match the first format that has the same channels */
1039  for (i = 0; i < renderer->info.num_texture_formats; ++i) {
1042  return renderer->info.texture_formats[i];
1043  }
1044  }
1045  }
1046  return renderer->info.texture_formats[0];
1047 }
1048 
1049 
1051 {
1052  const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
1053 
1054  if (!hint || SDL_strcasecmp(hint, "nearest") == 0) {
1055  return SDL_ScaleModeNearest;
1056  } else if (SDL_strcasecmp(hint, "linear") == 0) {
1057  return SDL_ScaleModeLinear;
1058  } else if (SDL_strcasecmp(hint, "best") == 0) {
1059  return SDL_ScaleModeBest;
1060  } else {
1061  return (SDL_ScaleMode)SDL_atoi(hint);
1062  }
1063 }
1064 
1065 SDL_Texture *
1067 {
1069 
1071 
1072  if (!format) {
1074  }
1075  if (SDL_BYTESPERPIXEL(format) == 0) {
1076  SDL_SetError("Invalid texture format");
1077  return NULL;
1078  }
1080  SDL_SetError("Palettized textures are not supported");
1081  return NULL;
1082  }
1083  if (w <= 0 || h <= 0) {
1084  SDL_SetError("Texture dimensions can't be 0");
1085  return NULL;
1086  }
1089  SDL_SetError("Texture dimensions are limited to %dx%d", renderer->info.max_texture_width, renderer->info.max_texture_height);
1090  return NULL;
1091  }
1092  texture = (SDL_Texture *) SDL_calloc(1, sizeof(*texture));
1093  if (!texture) {
1094  SDL_OutOfMemory();
1095  return NULL;
1096  }
1097  texture->magic = &texture_magic;
1098  texture->format = format;
1099  texture->access = access;
1100  texture->w = w;
1101  texture->h = h;
1102  texture->r = 255;
1103  texture->g = 255;
1104  texture->b = 255;
1105  texture->a = 255;
1106  texture->scaleMode = SDL_GetScaleMode();
1107  texture->renderer = renderer;
1108  texture->next = renderer->textures;
1109  if (renderer->textures) {
1111  }
1113 
1115  if (renderer->CreateTexture(renderer, texture) < 0) {
1117  return NULL;
1118  }
1119  } else {
1122  access, w, h);
1123  if (!texture->native) {
1125  return NULL;
1126  }
1127 
1128  /* Swap textures to have texture before texture->native in the list */
1129  texture->native->next = texture->next;
1130  if (texture->native->next) {
1131  texture->native->next->prev = texture->native;
1132  }
1133  texture->prev = texture->native->prev;
1134  if (texture->prev) {
1135  texture->prev->next = texture;
1136  }
1137  texture->native->prev = texture;
1138  texture->next = texture->native;
1140 
1141  if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
1142 #if SDL_HAVE_YUV
1144 #else
1145  SDL_SetError("SDL not built with YUV support");
1146 #endif
1147  if (!texture->yuv) {
1149  return NULL;
1150  }
1151  } else if (access == SDL_TEXTUREACCESS_STREAMING) {
1152  /* The pitch is 4 byte aligned */
1153  texture->pitch = (((w * SDL_BYTESPERPIXEL(format)) + 3) & ~3);
1154  texture->pixels = SDL_calloc(1, texture->pitch * h);
1155  if (!texture->pixels) {
1157  return NULL;
1158  }
1159  }
1160  }
1161  return texture;
1162 }
1163 
1164 SDL_Texture *
1166 {
1167  const SDL_PixelFormat *fmt;
1168  SDL_bool needAlpha;
1169  SDL_bool direct_update;
1170  int i;
1173 
1175 
1176  if (!surface) {
1177  SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
1178  return NULL;
1179  }
1180 
1181  /* See what the best texture format is */
1182  fmt = surface->format;
1183  if (fmt->Amask || SDL_HasColorKey(surface)) {
1184  needAlpha = SDL_TRUE;
1185  } else {
1186  needAlpha = SDL_FALSE;
1187  }
1188 
1189  /* If Palette contains alpha values, promotes to alpha format */
1190  if (fmt->palette) {
1191  SDL_bool is_opaque, has_alpha_channel;
1192  SDL_DetectPalette(fmt->palette, &is_opaque, &has_alpha_channel);
1193  if (!is_opaque) {
1194  needAlpha = SDL_TRUE;
1195  }
1196  }
1197 
1198  /* Try to have the best pixel format for the texture */
1199  /* No alpha, but a colorkey => promote to alpha */
1200  if (!fmt->Amask && SDL_HasColorKey(surface)) {
1201  if (fmt->format == SDL_PIXELFORMAT_RGB888) {
1202  for (i = 0; i < (int)renderer->info.num_texture_formats; ++i) {
1205  break;
1206  }
1207  }
1208  } else if (fmt->format == SDL_PIXELFORMAT_BGR888) {
1209  for (i = 0; i < (int)renderer->info.num_texture_formats; ++i) {
1212  break;
1213  }
1214  }
1215  }
1216  } else {
1217  /* Exact match would be fine */
1218  for (i = 0; i < (int)renderer->info.num_texture_formats; ++i) {
1219  if (renderer->info.texture_formats[i] == fmt->format) {
1220  format = fmt->format;
1221  break;
1222  }
1223  }
1224  }
1225 
1226  /* Fallback, choose a valid pixel format */
1229  for (i = 0; i < (int)renderer->info.num_texture_formats; ++i) {
1233  break;
1234  }
1235  }
1236  }
1237 
1239  surface->w, surface->h);
1240  if (!texture) {
1241  return NULL;
1242  }
1243 
1244  if (format == surface->format->format) {
1245  if (surface->format->Amask && SDL_HasColorKey(surface)) {
1246  /* Surface and Renderer formats are identicals.
1247  * Intermediate conversion is needed to convert color key to alpha (SDL_ConvertColorkeyToAlpha()). */
1248  direct_update = SDL_FALSE;
1249  } else {
1250  /* Update Texture directly */
1251  direct_update = SDL_TRUE;
1252  }
1253  } else {
1254  /* Surface and Renderer formats are differents, it needs an intermediate conversion. */
1255  direct_update = SDL_FALSE;
1256  }
1257 
1258  if (direct_update) {
1259  if (SDL_MUSTLOCK(surface)) {
1261  SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
1263  } else {
1264  SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
1265  }
1266  } else {
1267  SDL_PixelFormat *dst_fmt;
1268  SDL_Surface *temp = NULL;
1269 
1270  /* Set up a destination surface for the texture update */
1271  dst_fmt = SDL_AllocFormat(format);
1272  if (!dst_fmt) {
1274  return NULL;
1275  }
1276  temp = SDL_ConvertSurface(surface, dst_fmt, 0);
1277  SDL_FreeFormat(dst_fmt);
1278  if (temp) {
1279  SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
1280  SDL_FreeSurface(temp);
1281  } else {
1283  return NULL;
1284  }
1285  }
1286 
1287  {
1288  Uint8 r, g, b, a;
1290 
1293 
1296 
1297  if (SDL_HasColorKey(surface)) {
1298  /* We converted to a texture with alpha format */
1300  } else {
1303  }
1304  }
1305  return texture;
1306 }
1307 
1308 int
1310  int *w, int *h)
1311 {
1313 
1314  if (format) {
1315  *format = texture->format;
1316  }
1317  if (access) {
1318  *access = texture->access;
1319  }
1320  if (w) {
1321  *w = texture->w;
1322  }
1323  if (h) {
1324  *h = texture->h;
1325  }
1326  return 0;
1327 }
1328 
1329 int
1331 {
1333 
1334  if (r < 255 || g < 255 || b < 255) {
1335  texture->modMode |= SDL_TEXTUREMODULATE_COLOR;
1336  } else {
1337  texture->modMode &= ~SDL_TEXTUREMODULATE_COLOR;
1338  }
1339  texture->r = r;
1340  texture->g = g;
1341  texture->b = b;
1342  if (texture->native) {
1343  return SDL_SetTextureColorMod(texture->native, r, g, b);
1344  }
1345  return 0;
1346 }
1347 
1348 int
1350  Uint8 * b)
1351 {
1353 
1354  if (r) {
1355  *r = texture->r;
1356  }
1357  if (g) {
1358  *g = texture->g;
1359  }
1360  if (b) {
1361  *b = texture->b;
1362  }
1363  return 0;
1364 }
1365 
1366 int
1368 {
1370 
1371  if (alpha < 255) {
1372  texture->modMode |= SDL_TEXTUREMODULATE_ALPHA;
1373  } else {
1374  texture->modMode &= ~SDL_TEXTUREMODULATE_ALPHA;
1375  }
1376  texture->a = alpha;
1377  if (texture->native) {
1378  return SDL_SetTextureAlphaMod(texture->native, alpha);
1379  }
1380  return 0;
1381 }
1382 
1383 int
1385 {
1387 
1388  if (alpha) {
1389  *alpha = texture->a;
1390  }
1391  return 0;
1392 }
1393 
1394 int
1396 {
1398 
1400 
1401  renderer = texture->renderer;
1403  return SDL_Unsupported();
1404  }
1405  texture->blendMode = blendMode;
1406  if (texture->native) {
1407  return SDL_SetTextureBlendMode(texture->native, blendMode);
1408  }
1409  return 0;
1410 }
1411 
1412 int
1414 {
1416 
1417  if (blendMode) {
1418  *blendMode = texture->blendMode;
1419  }
1420  return 0;
1421 }
1422 
1423 int
1425 {
1427 
1429 
1430  renderer = texture->renderer;
1432  texture->scaleMode = scaleMode;
1433  if (texture->native) {
1434  return SDL_SetTextureScaleMode(texture->native, scaleMode);
1435  }
1436  return 0;
1437 }
1438 
1439 int
1441 {
1443 
1444  if (scaleMode) {
1445  *scaleMode = texture->scaleMode;
1446  }
1447  return 0;
1448 }
1449 
1450 #if SDL_HAVE_YUV
1451 static int
1453  const void *pixels, int pitch)
1454 {
1455  SDL_Texture *native = texture->native;
1456  SDL_Rect full_rect;
1457 
1458  if (SDL_SW_UpdateYUVTexture(texture->yuv, rect, pixels, pitch) < 0) {
1459  return -1;
1460  }
1461 
1462  full_rect.x = 0;
1463  full_rect.y = 0;
1464  full_rect.w = texture->w;
1465  full_rect.h = texture->h;
1466  rect = &full_rect;
1467 
1468  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
1469  /* We can lock the texture and copy to it */
1470  void *native_pixels = NULL;
1471  int native_pitch = 0;
1472 
1473  if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
1474  return -1;
1475  }
1476  SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
1477  rect->w, rect->h, native_pixels, native_pitch);
1478  SDL_UnlockTexture(native);
1479  } else {
1480  /* Use a temporary buffer for updating */
1481  const int temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3);
1482  const size_t alloclen = rect->h * temp_pitch;
1483  if (alloclen > 0) {
1484  void *temp_pixels = SDL_malloc(alloclen);
1485  if (!temp_pixels) {
1486  return SDL_OutOfMemory();
1487  }
1488  SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
1489  rect->w, rect->h, temp_pixels, temp_pitch);
1490  SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch);
1491  SDL_free(temp_pixels);
1492  }
1493  }
1494  return 0;
1495 }
1496 #endif /* SDL_HAVE_YUV */
1497 
1498 static int
1500  const void *pixels, int pitch)
1501 {
1502  SDL_Texture *native = texture->native;
1503 
1504  if (!rect->w || !rect->h) {
1505  return 0; /* nothing to do. */
1506  }
1507 
1508  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
1509  /* We can lock the texture and copy to it */
1510  void *native_pixels = NULL;
1511  int native_pitch = 0;
1512 
1513  if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
1514  return -1;
1515  }
1517  texture->format, pixels, pitch,
1518  native->format, native_pixels, native_pitch);
1519  SDL_UnlockTexture(native);
1520  } else {
1521  /* Use a temporary buffer for updating */
1522  const int temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3);
1523  const size_t alloclen = rect->h * temp_pitch;
1524  if (alloclen > 0) {
1525  void *temp_pixels = SDL_malloc(alloclen);
1526  if (!temp_pixels) {
1527  return SDL_OutOfMemory();
1528  }
1530  texture->format, pixels, pitch,
1531  native->format, temp_pixels, temp_pitch);
1532  SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch);
1533  SDL_free(temp_pixels);
1534  }
1535  }
1536  return 0;
1537 }
1538 
1539 int
1541  const void *pixels, int pitch)
1542 {
1543  SDL_Rect full_rect;
1544 
1546 
1547  if (!pixels) {
1548  return SDL_InvalidParamError("pixels");
1549  }
1550  if (!pitch) {
1551  return SDL_InvalidParamError("pitch");
1552  }
1553 
1554  if (!rect) {
1555  full_rect.x = 0;
1556  full_rect.y = 0;
1557  full_rect.w = texture->w;
1558  full_rect.h = texture->h;
1559  rect = &full_rect;
1560  }
1561 
1562  if ((rect->w == 0) || (rect->h == 0)) {
1563  return 0; /* nothing to do. */
1564 #if SDL_HAVE_YUV
1565  } else if (texture->yuv) {
1566  return SDL_UpdateTextureYUV(texture, rect, pixels, pitch);
1567 #endif
1568  } else if (texture->native) {
1569  return SDL_UpdateTextureNative(texture, rect, pixels, pitch);
1570  } else {
1571  SDL_Renderer *renderer = texture->renderer;
1573  return -1;
1574  }
1575  return renderer->UpdateTexture(renderer, texture, rect, pixels, pitch);
1576  }
1577 }
1578 
1579 #if SDL_HAVE_YUV
1580 static int
1582  const Uint8 *Yplane, int Ypitch,
1583  const Uint8 *Uplane, int Upitch,
1584  const Uint8 *Vplane, int Vpitch)
1585 {
1586  SDL_Texture *native = texture->native;
1587  SDL_Rect full_rect;
1588 
1589  if (SDL_SW_UpdateYUVTexturePlanar(texture->yuv, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch) < 0) {
1590  return -1;
1591  }
1592 
1593  full_rect.x = 0;
1594  full_rect.y = 0;
1595  full_rect.w = texture->w;
1596  full_rect.h = texture->h;
1597  rect = &full_rect;
1598 
1599  if (!rect->w || !rect->h) {
1600  return 0; /* nothing to do. */
1601  }
1602 
1603  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
1604  /* We can lock the texture and copy to it */
1605  void *native_pixels = NULL;
1606  int native_pitch = 0;
1607 
1608  if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
1609  return -1;
1610  }
1611  SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
1612  rect->w, rect->h, native_pixels, native_pitch);
1613  SDL_UnlockTexture(native);
1614  } else {
1615  /* Use a temporary buffer for updating */
1616  const int temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3);
1617  const size_t alloclen = rect->h * temp_pitch;
1618  if (alloclen > 0) {
1619  void *temp_pixels = SDL_malloc(alloclen);
1620  if (!temp_pixels) {
1621  return SDL_OutOfMemory();
1622  }
1623  SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
1624  rect->w, rect->h, temp_pixels, temp_pitch);
1625  SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch);
1626  SDL_free(temp_pixels);
1627  }
1628  }
1629  return 0;
1630 }
1631 #endif /* SDL_HAVE_YUV */
1632 
1634  const Uint8 *Yplane, int Ypitch,
1635  const Uint8 *Uplane, int Upitch,
1636  const Uint8 *Vplane, int Vpitch)
1637 {
1638 #if SDL_HAVE_YUV
1640  SDL_Rect full_rect;
1641 
1643 
1644  if (!Yplane) {
1645  return SDL_InvalidParamError("Yplane");
1646  }
1647  if (!Ypitch) {
1648  return SDL_InvalidParamError("Ypitch");
1649  }
1650  if (!Uplane) {
1651  return SDL_InvalidParamError("Uplane");
1652  }
1653  if (!Upitch) {
1654  return SDL_InvalidParamError("Upitch");
1655  }
1656  if (!Vplane) {
1657  return SDL_InvalidParamError("Vplane");
1658  }
1659  if (!Vpitch) {
1660  return SDL_InvalidParamError("Vpitch");
1661  }
1662 
1663  if (texture->format != SDL_PIXELFORMAT_YV12 &&
1664  texture->format != SDL_PIXELFORMAT_IYUV) {
1665  return SDL_SetError("Texture format must by YV12 or IYUV");
1666  }
1667 
1668  if (!rect) {
1669  full_rect.x = 0;
1670  full_rect.y = 0;
1671  full_rect.w = texture->w;
1672  full_rect.h = texture->h;
1673  rect = &full_rect;
1674  }
1675 
1676  if (!rect->w || !rect->h) {
1677  return 0; /* nothing to do. */
1678  }
1679 
1680  if (texture->yuv) {
1681  return SDL_UpdateTextureYUVPlanar(texture, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
1682  } else {
1683  SDL_assert(!texture->native);
1684  renderer = texture->renderer;
1686  if (renderer->UpdateTextureYUV) {
1688  return -1;
1689  }
1690  return renderer->UpdateTextureYUV(renderer, texture, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
1691  } else {
1692  return SDL_Unsupported();
1693  }
1694  }
1695 #else
1696  return -1;
1697 #endif
1698 }
1699 
1700 #if SDL_HAVE_YUV
1701 static int
1703  void **pixels, int *pitch)
1704 {
1705  return SDL_SW_LockYUVTexture(texture->yuv, rect, pixels, pitch);
1706 }
1707 #endif /* SDL_HAVE_YUV */
1708 
1709 static int
1711  void **pixels, int *pitch)
1712 {
1713  texture->locked_rect = *rect;
1714  *pixels = (void *) ((Uint8 *) texture->pixels +
1715  rect->y * texture->pitch +
1716  rect->x * SDL_BYTESPERPIXEL(texture->format));
1717  *pitch = texture->pitch;
1718  return 0;
1719 }
1720 
1721 int
1723  void **pixels, int *pitch)
1724 {
1725  SDL_Rect full_rect;
1726 
1728 
1729  if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
1730  return SDL_SetError("SDL_LockTexture(): texture must be streaming");
1731  }
1732 
1733  if (!rect) {
1734  full_rect.x = 0;
1735  full_rect.y = 0;
1736  full_rect.w = texture->w;
1737  full_rect.h = texture->h;
1738  rect = &full_rect;
1739  }
1740 
1741 #if SDL_HAVE_YUV
1742  if (texture->yuv) {
1744  return -1;
1745  }
1746  return SDL_LockTextureYUV(texture, rect, pixels, pitch);
1747  } else
1748 #endif
1749  if (texture->native) {
1750  /* Calls a real SDL_LockTexture/SDL_UnlockTexture on unlock, flushing then. */
1751  return SDL_LockTextureNative(texture, rect, pixels, pitch);
1752  } else {
1753  SDL_Renderer *renderer = texture->renderer;
1755  return -1;
1756  }
1757  return renderer->LockTexture(renderer, texture, rect, pixels, pitch);
1758  }
1759 }
1760 
1761 int
1763  SDL_Surface **surface)
1764 {
1765  SDL_Rect real_rect;
1766  void *pixels = NULL;
1767  int pitch = 0; /* fix static analysis */
1768  int ret;
1769 
1770  if (texture == NULL || surface == NULL) {
1771  return -1;
1772  }
1773 
1774  real_rect.x = 0;
1775  real_rect.y = 0;
1776  real_rect.w = texture->w;
1777  real_rect.h = texture->h;
1778 
1779  if (rect) {
1780  SDL_IntersectRect(rect, &real_rect, &real_rect);
1781  }
1782 
1783  ret = SDL_LockTexture(texture, &real_rect, &pixels, &pitch);
1784  if (ret < 0) {
1785  return ret;
1786  }
1787 
1788  texture->locked_surface = SDL_CreateRGBSurfaceWithFormatFrom(pixels, real_rect.w, real_rect.h, 0, pitch, texture->format);
1789  if (texture->locked_surface == NULL) {
1791  return -1;
1792  }
1793 
1794  *surface = texture->locked_surface;
1795  return 0;
1796 }
1797 
1798 #if SDL_HAVE_YUV
1799 static void
1801 {
1802  SDL_Texture *native = texture->native;
1803  void *native_pixels = NULL;
1804  int native_pitch = 0;
1805  SDL_Rect rect;
1806 
1807  rect.x = 0;
1808  rect.y = 0;
1809  rect.w = texture->w;
1810  rect.h = texture->h;
1811 
1812  if (SDL_LockTexture(native, &rect, &native_pixels, &native_pitch) < 0) {
1813  return;
1814  }
1815  SDL_SW_CopyYUVToRGB(texture->yuv, &rect, native->format,
1816  rect.w, rect.h, native_pixels, native_pitch);
1817  SDL_UnlockTexture(native);
1818 }
1819 #endif /* SDL_HAVE_YUV */
1820 
1821 static void
1823 {
1824  SDL_Texture *native = texture->native;
1825  void *native_pixels = NULL;
1826  int native_pitch = 0;
1827  const SDL_Rect *rect = &texture->locked_rect;
1828  const void* pixels = (void *) ((Uint8 *) texture->pixels +
1829  rect->y * texture->pitch +
1830  rect->x * SDL_BYTESPERPIXEL(texture->format));
1831  int pitch = texture->pitch;
1832 
1833  if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
1834  return;
1835  }
1837  texture->format, pixels, pitch,
1838  native->format, native_pixels, native_pitch);
1839  SDL_UnlockTexture(native);
1840 }
1841 
1842 void
1844 {
1846 
1847  if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
1848  return;
1849  }
1850 #if SDL_HAVE_YUV
1851  if (texture->yuv) {
1853  } else
1854 #endif
1855  if (texture->native) {
1857  } else {
1858  SDL_Renderer *renderer = texture->renderer;
1860  }
1861 
1862  SDL_FreeSurface(texture->locked_surface);
1863  texture->locked_surface = NULL;
1864 }
1865 
1866 SDL_bool
1868 {
1869  if (!renderer || !renderer->SetRenderTarget) {
1870  return SDL_FALSE;
1871  }
1872  return (renderer->info.flags & SDL_RENDERER_TARGETTEXTURE) != 0;
1873 }
1874 
1875 int
1877 {
1879  return SDL_Unsupported();
1880  }
1881 
1882  /* texture == NULL is valid and means reset the target to the window */
1883  if (texture) {
1885  if (renderer != texture->renderer) {
1886  return SDL_SetError("Texture was not created with this renderer");
1887  }
1888  if (texture->access != SDL_TEXTUREACCESS_TARGET) {
1889  return SDL_SetError("Texture not created with SDL_TEXTUREACCESS_TARGET");
1890  }
1891  if (texture->native) {
1892  /* Always render to the native texture */
1893  texture = texture->native;
1894  }
1895  }
1896 
1897  if (texture == renderer->target) {
1898  /* Nothing to do! */
1899  return 0;
1900  }
1901 
1902  FlushRenderCommands(renderer); /* time to send everything to the GPU! */
1903 
1905 
1906  if (texture && !renderer->target) {
1907  /* Make a backup of the viewport */
1914  }
1915  renderer->target = texture;
1916 
1919  return -1;
1920  }
1921 
1922  if (texture) {
1923  renderer->viewport.x = 0;
1924  renderer->viewport.y = 0;
1925  renderer->viewport.w = texture->w;
1926  renderer->viewport.h = texture->h;
1929  renderer->scale.x = 1.0f;
1930  renderer->scale.y = 1.0f;
1931  renderer->logical_w = texture->w;
1932  renderer->logical_h = texture->h;
1933  } else {
1940  }
1941 
1943 
1944  if (QueueCmdSetViewport(renderer) < 0) {
1945  return -1;
1946  }
1947  if (QueueCmdSetClipRect(renderer) < 0) {
1948  return -1;
1949  }
1950 
1951  /* All set! */
1953 }
1954 
1955 SDL_Texture *
1957 {
1958  return renderer->target;
1959 }
1960 
1961 static int
1963 {
1964  int w = 1, h = 1;
1965  float want_aspect;
1966  float real_aspect;
1967  float scale;
1969  /* 0 is for letterbox, 1 is for overscan */
1970  int scale_policy = 0;
1971  const char *hint;
1972 
1973  if (!renderer->logical_w || !renderer->logical_h) {
1974  return 0;
1975  }
1976  if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) {
1977  return -1;
1978  }
1979 
1981  if (hint && (*hint == '1' || SDL_strcasecmp(hint, "overscan") == 0)) {
1982 #if SDL_VIDEO_RENDER_D3D
1983  SDL_bool overscan_supported = SDL_TRUE;
1984  /* Unfortunately, Direct3D 9 doesn't support negative viewport numbers
1985  which the overscan implementation relies on.
1986  */
1987  if (SDL_strcasecmp(SDL_GetCurrentVideoDriver(), "direct3d") == 0) {
1988  overscan_supported = SDL_FALSE;
1989  }
1990  if (overscan_supported) {
1991  scale_policy = 1;
1992  }
1993 #else
1994  scale_policy = 1;
1995 #endif
1996  }
1997 
1998  want_aspect = (float)renderer->logical_w / renderer->logical_h;
1999  real_aspect = (float)w / h;
2000 
2001  /* Clear the scale because we're setting viewport in output coordinates */
2002  SDL_RenderSetScale(renderer, 1.0f, 1.0f);
2003 
2004  if (renderer->integer_scale) {
2005  if (want_aspect > real_aspect) {
2006  scale = (float)(w / renderer->logical_w);
2007  } else {
2008  scale = (float)(h / renderer->logical_h);
2009  }
2011  viewport.x = (w - viewport.w) / 2;
2013  viewport.y = (h - viewport.h) / 2;
2014 
2016  } else if (SDL_fabs(want_aspect-real_aspect) < 0.0001) {
2017  /* The aspect ratios are the same, just scale appropriately */
2018  scale = (float)w / renderer->logical_w;
2020  } else if (want_aspect > real_aspect) {
2021  if (scale_policy == 1) {
2022  /* We want a wider aspect ratio than is available -
2023  zoom so logical height matches the real height
2024  and the width will grow off the screen
2025  */
2026  scale = (float)h / renderer->logical_h;
2027  viewport.y = 0;
2028  viewport.h = h;
2030  viewport.x = (w - viewport.w) / 2;
2032  } else {
2033  /* We want a wider aspect ratio than is available - letterbox it */
2034  scale = (float)w / renderer->logical_w;
2035  viewport.x = 0;
2036  viewport.w = w;
2038  viewport.y = (h - viewport.h) / 2;
2040  }
2041  } else {
2042  if (scale_policy == 1) {
2043  /* We want a narrower aspect ratio than is available -
2044  zoom so logical width matches the real width
2045  and the height will grow off the screen
2046  */
2047  scale = (float)w / renderer->logical_w;
2048  viewport.x = 0;
2049  viewport.w = w;
2051  viewport.y = (h - viewport.h) / 2;
2053  } else {
2054  /* We want a narrower aspect ratio than is available - use side-bars */
2055  scale = (float)h / renderer->logical_h;
2056  viewport.y = 0;
2057  viewport.h = h;
2059  viewport.x = (w - viewport.w) / 2;
2061  }
2062  }
2063 
2064  /* Set the new scale */
2066 
2067  return 0;
2068 }
2069 
2070 int
2072 {
2074 
2075  if (!w || !h) {
2076  /* Clear any previous logical resolution */
2077  renderer->logical_w = 0;
2078  renderer->logical_h = 0;
2080  SDL_RenderSetScale(renderer, 1.0f, 1.0f);
2081  return 0;
2082  }
2083 
2084  renderer->logical_w = w;
2085  renderer->logical_h = h;
2086 
2087  return UpdateLogicalSize(renderer);
2088 }
2089 
2090 void
2092 {
2094 
2095  if (w) {
2096  *w = renderer->logical_w;
2097  }
2098  if (h) {
2099  *h = renderer->logical_h;
2100  }
2101 }
2102 
2103 int
2105 {
2107 
2109 
2110  return UpdateLogicalSize(renderer);
2111 }
2112 
2113 SDL_bool
2115 {
2117 
2118  return renderer->integer_scale;
2119 }
2120 
2121 int
2123 {
2124  int retval;
2126 
2127  if (rect) {
2132  } else {
2133  renderer->viewport.x = 0;
2134  renderer->viewport.y = 0;
2136  return -1;
2137  }
2138  }
2141 }
2142 
2143 void
2145 {
2147 
2148  if (rect) {
2149  rect->x = (int)(renderer->viewport.x / renderer->scale.x);
2150  rect->y = (int)(renderer->viewport.y / renderer->scale.y);
2151  rect->w = (int)(renderer->viewport.w / renderer->scale.x);
2152  rect->h = (int)(renderer->viewport.h / renderer->scale.y);
2153  }
2154 }
2155 
2156 int
2158 {
2159  int retval;
2161 
2162  if (rect) {
2168  } else {
2171  }
2172 
2175 }
2176 
2177 void
2179 {
2181 
2182  if (rect) {
2183  rect->x = (int)(renderer->clip_rect.x / renderer->scale.x);
2184  rect->y = (int)(renderer->clip_rect.y / renderer->scale.y);
2185  rect->w = (int)(renderer->clip_rect.w / renderer->scale.x);
2186  rect->h = (int)(renderer->clip_rect.h / renderer->scale.y);
2187  }
2188 }
2189 
2190 SDL_bool
2192 {
2194  return renderer->clipping_enabled;
2195 }
2196 
2197 int
2198 SDL_RenderSetScale(SDL_Renderer * renderer, float scaleX, float scaleY)
2199 {
2201 
2202  renderer->scale.x = scaleX;
2203  renderer->scale.y = scaleY;
2204  return 0;
2205 }
2206 
2207 void
2208 SDL_RenderGetScale(SDL_Renderer * renderer, float *scaleX, float *scaleY)
2209 {
2211 
2212  if (scaleX) {
2213  *scaleX = renderer->scale.x;
2214  }
2215  if (scaleY) {
2216  *scaleY = renderer->scale.y;
2217  }
2218 }
2219 
2220 int
2222  Uint8 r, Uint8 g, Uint8 b, Uint8 a)
2223 {
2225 
2226  renderer->r = r;
2227  renderer->g = g;
2228  renderer->b = b;
2229  renderer->a = a;
2230  return 0;
2231 }
2232 
2233 int
2235  Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a)
2236 {
2238 
2239  if (r) {
2240  *r = renderer->r;
2241  }
2242  if (g) {
2243  *g = renderer->g;
2244  }
2245  if (b) {
2246  *b = renderer->b;
2247  }
2248  if (a) {
2249  *a = renderer->a;
2250  }
2251  return 0;
2252 }
2253 
2254 int
2256 {
2258 
2260  return SDL_Unsupported();
2261  }
2263  return 0;
2264 }
2265 
2266 int
2268 {
2270 
2272  return 0;
2273 }
2274 
2275 int
2277 {
2278  int retval;
2282 }
2283 
2284 
2285 /* !!! FIXME: delete all the duplicate code for the integer versions in 2.1,
2286  !!! FIXME: making the floating point versions the only available APIs. */
2287 
2288 int
2290 {
2291  SDL_FPoint fpoint;
2292  fpoint.x = (float) x;
2293  fpoint.y = (float) y;
2294  return SDL_RenderDrawPointsF(renderer, &fpoint, 1);
2295 }
2296 
2297 int
2299 {
2300  SDL_FPoint fpoint;
2301  fpoint.x = x;
2302  fpoint.y = y;
2303  return SDL_RenderDrawPointsF(renderer, &fpoint, 1);
2304 }
2305 
2306 static int
2308  const SDL_Point * points, const int count)
2309 {
2310  int retval = -1;
2311  SDL_bool isstack;
2312  SDL_FRect *frects = SDL_small_alloc(SDL_FRect, count, &isstack);
2313  int i;
2314 
2315  if (!frects) {
2316  return SDL_OutOfMemory();
2317  }
2318 
2319  for (i = 0; i < count; ++i) {
2320  frects[i].x = points[i].x * renderer->scale.x;
2321  frects[i].y = points[i].y * renderer->scale.y;
2322  frects[i].w = renderer->scale.x;
2323  frects[i].h = renderer->scale.y;
2324  }
2325 
2326  retval = QueueCmdFillRects(renderer, frects, count);
2327 
2328  SDL_small_free(frects, isstack);
2329 
2331 }
2332 
2333 int
2335  const SDL_Point * points, int count)
2336 {
2337  SDL_FPoint *fpoints;
2338  int i;
2339  int retval;
2340  SDL_bool isstack;
2341 
2343 
2344  if (!points) {
2345  return SDL_SetError("SDL_RenderDrawPoints(): Passed NULL points");
2346  }
2347  if (count < 1) {
2348  return 0;
2349  }
2350 
2351  /* Don't draw while we're hidden */
2352  if (renderer->hidden) {
2353  return 0;
2354  }
2355 
2356  if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
2358  }
2359 
2360  fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack);
2361  if (!fpoints) {
2362  return SDL_OutOfMemory();
2363  }
2364  for (i = 0; i < count; ++i) {
2365  fpoints[i].x = points[i].x * renderer->scale.x;
2366  fpoints[i].y = points[i].y * renderer->scale.y;
2367  }
2368 
2369  retval = QueueCmdDrawPoints(renderer, fpoints, count);
2370 
2371  SDL_small_free(fpoints, isstack);
2372 
2374 }
2375 
2376 static int
2378  const SDL_FPoint * fpoints, const int count)
2379 {
2380  int retval = -1;
2381  SDL_bool isstack;
2382  SDL_FRect *frects = SDL_small_alloc(SDL_FRect, count, &isstack);
2383  int i;
2384 
2385  if (!frects) {
2386  return SDL_OutOfMemory();
2387  }
2388 
2389  for (i = 0; i < count; ++i) {
2390  frects[i].x = fpoints[i].x * renderer->scale.x;
2391  frects[i].y = fpoints[i].y * renderer->scale.y;
2392  frects[i].w = renderer->scale.x;
2393  frects[i].h = renderer->scale.y;
2394  }
2395 
2396  retval = QueueCmdFillRects(renderer, frects, count);
2397 
2398  SDL_small_free(frects, isstack);
2399 
2401 }
2402 
2403 int
2405  const SDL_FPoint * points, int count)
2406 {
2407  SDL_FPoint *fpoints;
2408  int i;
2409  int retval;
2410  SDL_bool isstack;
2411 
2413 
2414  if (!points) {
2415  return SDL_SetError("SDL_RenderDrawFPoints(): Passed NULL points");
2416  }
2417  if (count < 1) {
2418  return 0;
2419  }
2420 
2421  /* Don't draw while we're hidden */
2422  if (renderer->hidden) {
2423  return 0;
2424  }
2425 
2426  if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
2428  }
2429 
2430  fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack);
2431  if (!fpoints) {
2432  return SDL_OutOfMemory();
2433  }
2434  for (i = 0; i < count; ++i) {
2435  fpoints[i].x = points[i].x * renderer->scale.x;
2436  fpoints[i].y = points[i].y * renderer->scale.y;
2437  }
2438 
2439  retval = QueueCmdDrawPoints(renderer, fpoints, count);
2440 
2441  SDL_small_free(fpoints, isstack);
2442 
2444 }
2445 
2446 int
2448 {
2449  SDL_FPoint points[2];
2450  points[0].x = (float) x1;
2451  points[0].y = (float) y1;
2452  points[1].x = (float) x2;
2453  points[1].y = (float) y2;
2454  return SDL_RenderDrawLinesF(renderer, points, 2);
2455 }
2456 
2457 int
2458 SDL_RenderDrawLineF(SDL_Renderer * renderer, float x1, float y1, float x2, float y2)
2459 {
2460  SDL_FPoint points[2];
2461  points[0].x = x1;
2462  points[0].y = y1;
2463  points[1].x = x2;
2464  points[1].y = y2;
2465  return SDL_RenderDrawLinesF(renderer, points, 2);
2466 }
2467 
2468 static int
2470  const SDL_Point * points, const int count)
2471 {
2472  SDL_FRect *frect;
2473  SDL_FRect *frects;
2474  SDL_FPoint fpoints[2];
2475  int i, nrects = 0;
2476  int retval = 0;
2477  SDL_bool isstack;
2478 
2479  frects = SDL_small_alloc(SDL_FRect, count-1, &isstack);
2480  if (!frects) {
2481  return SDL_OutOfMemory();
2482  }
2483 
2484  for (i = 0; i < count-1; ++i) {
2485  if (points[i].x == points[i+1].x) {
2486  const int minY = SDL_min(points[i].y, points[i+1].y);
2487  const int maxY = SDL_max(points[i].y, points[i+1].y);
2488 
2489  frect = &frects[nrects++];
2490  frect->x = points[i].x * renderer->scale.x;
2491  frect->y = minY * renderer->scale.y;
2492  frect->w = renderer->scale.x;
2493  frect->h = (maxY - minY + 1) * renderer->scale.y;
2494  } else if (points[i].y == points[i+1].y) {
2495  const int minX = SDL_min(points[i].x, points[i+1].x);
2496  const int maxX = SDL_max(points[i].x, points[i+1].x);
2497 
2498  frect = &frects[nrects++];
2499  frect->x = minX * renderer->scale.x;
2500  frect->y = points[i].y * renderer->scale.y;
2501  frect->w = (maxX - minX + 1) * renderer->scale.x;
2502  frect->h = renderer->scale.y;
2503  } else {
2504  /* FIXME: We can't use a rect for this line... */
2505  fpoints[0].x = points[i].x * renderer->scale.x;
2506  fpoints[0].y = points[i].y * renderer->scale.y;
2507  fpoints[1].x = points[i+1].x * renderer->scale.x;
2508  fpoints[1].y = points[i+1].y * renderer->scale.y;
2509  retval += QueueCmdDrawLines(renderer, fpoints, 2);
2510  }
2511  }
2512 
2513  retval += QueueCmdFillRects(renderer, frects, nrects);
2514 
2515  SDL_small_free(frects, isstack);
2516 
2517  if (retval < 0) {
2518  retval = -1;
2519  }
2521 }
2522 
2523 static int
2525  const SDL_FPoint * points, const int count)
2526 {
2527  SDL_FRect *frect;
2528  SDL_FRect *frects;
2529  SDL_FPoint fpoints[2];
2530  int i, nrects = 0;
2531  int retval = 0;
2532  SDL_bool isstack;
2533 
2534  frects = SDL_small_alloc(SDL_FRect, count-1, &isstack);
2535  if (!frects) {
2536  return SDL_OutOfMemory();
2537  }
2538 
2539  for (i = 0; i < count-1; ++i) {
2540  if (points[i].x == points[i+1].x) {
2541  const int minY = (int)SDL_min(points[i].y, points[i+1].y);
2542  const int maxY = (int)SDL_max(points[i].y, points[i+1].y);
2543 
2544  frect = &frects[nrects++];
2545  frect->x = points[i].x * renderer->scale.x;
2546  frect->y = minY * renderer->scale.y;
2547  frect->w = renderer->scale.x;
2548  frect->h = (maxY - minY + 1) * renderer->scale.y;
2549  } else if (points[i].y == points[i+1].y) {
2550  const int minX = (int)SDL_min(points[i].x, points[i+1].x);
2551  const int maxX = (int)SDL_max(points[i].x, points[i+1].x);
2552 
2553  frect = &frects[nrects++];
2554  frect->x = minX * renderer->scale.x;
2555  frect->y = points[i].y * renderer->scale.y;
2556  frect->w = (maxX - minX + 1) * renderer->scale.x;
2557  frect->h = renderer->scale.y;
2558  } else {
2559  /* FIXME: We can't use a rect for this line... */
2560  fpoints[0].x = points[i].x * renderer->scale.x;
2561  fpoints[0].y = points[i].y * renderer->scale.y;
2562  fpoints[1].x = points[i+1].x * renderer->scale.x;
2563  fpoints[1].y = points[i+1].y * renderer->scale.y;
2564  retval += QueueCmdDrawLines(renderer, fpoints, 2);
2565  }
2566  }
2567 
2568  retval += QueueCmdFillRects(renderer, frects, nrects);
2569 
2570  SDL_small_free(frects, isstack);
2571 
2572  if (retval < 0) {
2573  retval = -1;
2574  }
2576 }
2577 
2578 int
2580  const SDL_Point * points, int count)
2581 {
2582  SDL_FPoint *fpoints;
2583  int i;
2584  int retval;
2585  SDL_bool isstack;
2586 
2588 
2589  if (!points) {
2590  return SDL_SetError("SDL_RenderDrawLines(): Passed NULL points");
2591  }
2592  if (count < 2) {
2593  return 0;
2594  }
2595 
2596  /* Don't draw while we're hidden */
2597  if (renderer->hidden) {
2598  return 0;
2599  }
2600 
2601  if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
2603  }
2604 
2605  fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack);
2606  if (!fpoints) {
2607  return SDL_OutOfMemory();
2608  }
2609  for (i = 0; i < count; ++i) {
2610  fpoints[i].x = points[i].x * renderer->scale.x;
2611  fpoints[i].y = points[i].y * renderer->scale.y;
2612  }
2613 
2614  retval = QueueCmdDrawLines(renderer, fpoints, count);
2615 
2616  SDL_small_free(fpoints, isstack);
2617 
2619 }
2620 
2621 int
2623  const SDL_FPoint * points, int count)
2624 {
2625  SDL_FPoint *fpoints;
2626  int i;
2627  int retval;
2628  SDL_bool isstack;
2629 
2631 
2632  if (!points) {
2633  return SDL_SetError("SDL_RenderDrawLines(): Passed NULL points");
2634  }
2635  if (count < 2) {
2636  return 0;
2637  }
2638 
2639  /* Don't draw while we're hidden */
2640  if (renderer->hidden) {
2641  return 0;
2642  }
2643 
2644  if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
2646  }
2647 
2648  fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack);
2649  if (!fpoints) {
2650  return SDL_OutOfMemory();
2651  }
2652  for (i = 0; i < count; ++i) {
2653  fpoints[i].x = points[i].x * renderer->scale.x;
2654  fpoints[i].y = points[i].y * renderer->scale.y;
2655  }
2656 
2657  retval = QueueCmdDrawLines(renderer, fpoints, count);
2658 
2659  SDL_small_free(fpoints, isstack);
2660 
2662 }
2663 
2664 int
2666 {
2667  SDL_FRect frect;
2668  SDL_FRect *prect = NULL;
2669 
2670  if (rect) {
2671  frect.x = (float) rect->x;
2672  frect.y = (float) rect->y;
2673  frect.w = (float) rect->w;
2674  frect.h = (float) rect->h;
2675  prect = &frect;
2676  }
2677 
2678  return SDL_RenderDrawRectF(renderer, prect);
2679 }
2680 
2681 int
2683 {
2684  SDL_FRect frect;
2685  SDL_FPoint points[5];
2686 
2688 
2689  /* If 'rect' == NULL, then outline the whole surface */
2690  if (!rect) {
2691  SDL_Rect r;
2693  frect.x = 0.0f;
2694  frect.y = 0.0f;
2695  frect.w = (float) r.w;
2696  frect.h = (float) r.h;
2697  rect = &frect;
2698  }
2699 
2700  points[0].x = rect->x;
2701  points[0].y = rect->y;
2702  points[1].x = rect->x+rect->w-1;
2703  points[1].y = rect->y;
2704  points[2].x = rect->x+rect->w-1;
2705  points[2].y = rect->y+rect->h-1;
2706  points[3].x = rect->x;
2707  points[3].y = rect->y+rect->h-1;
2708  points[4].x = rect->x;
2709  points[4].y = rect->y;
2710  return SDL_RenderDrawLinesF(renderer, points, 5);
2711 }
2712 
2713 int
2715  const SDL_Rect * rects, int count)
2716 {
2717  int i;
2718 
2720 
2721  if (!rects) {
2722  return SDL_SetError("SDL_RenderDrawRects(): Passed NULL rects");
2723  }
2724  if (count < 1) {
2725  return 0;
2726  }
2727 
2728  /* Don't draw while we're hidden */
2729  if (renderer->hidden) {
2730  return 0;
2731  }
2732 
2733  for (i = 0; i < count; ++i) {
2734  if (SDL_RenderDrawRect(renderer, &rects[i]) < 0) {
2735  return -1;
2736  }
2737  }
2738  return 0;
2739 }
2740 
2741 int
2743  const SDL_FRect * rects, int count)
2744 {
2745  int i;
2746 
2748 
2749  if (!rects) {
2750  return SDL_SetError("SDL_RenderDrawRects(): Passed NULL rects");
2751  }
2752  if (count < 1) {
2753  return 0;
2754  }
2755 
2756  /* Don't draw while we're hidden */
2757  if (renderer->hidden) {
2758  return 0;
2759  }
2760 
2761  for (i = 0; i < count; ++i) {
2762  if (SDL_RenderDrawRectF(renderer, &rects[i]) < 0) {
2763  return -1;
2764  }
2765  }
2766  return 0;
2767 }
2768 
2769 int
2771 {
2772  SDL_FRect frect;
2773 
2775 
2776  /* If 'rect' == NULL, then outline the whole surface */
2777  if (rect) {
2778  frect.x = (float) rect->x;
2779  frect.y = (float) rect->y;
2780  frect.w = (float) rect->w;
2781  frect.h = (float) rect->h;
2782  } else {
2783  SDL_Rect r;
2784  SDL_zero(r);
2786  frect.x = 0.0f;
2787  frect.y = 0.0f;
2788  frect.w = (float) r.w;
2789  frect.h = (float) r.h;
2790  }
2791  return SDL_RenderFillRectsF(renderer, &frect, 1);
2792 }
2793 
2794 int
2796 {
2797  SDL_FRect frect;
2798 
2800 
2801  /* If 'rect' == NULL, then outline the whole surface */
2802  if (!rect) {
2803  SDL_Rect r;
2804  SDL_zero(r);
2806  frect.x = 0.0f;
2807  frect.y = 0.0f;
2808  frect.w = (float) r.w;
2809  frect.h = (float) r.h;
2810  rect = &frect;
2811  }
2812  return SDL_RenderFillRectsF(renderer, rect, 1);
2813 }
2814 
2815 int
2817  const SDL_Rect * rects, int count)
2818 {
2819  SDL_FRect *frects;
2820  int i;
2821  int retval;
2822  SDL_bool isstack;
2823 
2825 
2826  if (!rects) {
2827  return SDL_SetError("SDL_RenderFillRects(): Passed NULL rects");
2828  }
2829  if (count < 1) {
2830  return 0;
2831  }
2832 
2833  /* Don't draw while we're hidden */
2834  if (renderer->hidden) {
2835  return 0;
2836  }
2837 
2838  frects = SDL_small_alloc(SDL_FRect, count, &isstack);
2839  if (!frects) {
2840  return SDL_OutOfMemory();
2841  }
2842  for (i = 0; i < count; ++i) {
2843  frects[i].x = rects[i].x * renderer->scale.x;
2844  frects[i].y = rects[i].y * renderer->scale.y;
2845  frects[i].w = rects[i].w * renderer->scale.x;
2846  frects[i].h = rects[i].h * renderer->scale.y;
2847  }
2848 
2849  retval = QueueCmdFillRects(renderer, frects, count);
2850 
2851  SDL_small_free(frects, isstack);
2852 
2854 }
2855 
2856 int
2858  const SDL_FRect * rects, int count)
2859 {
2860  SDL_FRect *frects;
2861  int i;
2862  int retval;
2863  SDL_bool isstack;
2864 
2866 
2867  if (!rects) {
2868  return SDL_SetError("SDL_RenderFillFRects(): Passed NULL rects");
2869  }
2870  if (count < 1) {
2871  return 0;
2872  }
2873 
2874  /* Don't draw while we're hidden */
2875  if (renderer->hidden) {
2876  return 0;
2877  }
2878 
2879  frects = SDL_small_alloc(SDL_FRect, count, &isstack);
2880  if (!frects) {
2881  return SDL_OutOfMemory();
2882  }
2883  for (i = 0; i < count; ++i) {
2884  frects[i].x = rects[i].x * renderer->scale.x;
2885  frects[i].y = rects[i].y * renderer->scale.y;
2886  frects[i].w = rects[i].w * renderer->scale.x;
2887  frects[i].h = rects[i].h * renderer->scale.y;
2888  }
2889 
2890  retval = QueueCmdFillRects(renderer, frects, count);
2891 
2892  SDL_small_free(frects, isstack);
2893 
2895 }
2896 
2897 /* !!! FIXME: move this to a public API if we want to do float versions of all of these later */
2899 {
2900  return ((!r) || (r->w <= 0.0f) || (r->h <= 0.0f)) ? SDL_TRUE : SDL_FALSE;
2901 }
2902 
2903 /* !!! FIXME: move this to a public API if we want to do float versions of all of these later */
2904 static SDL_bool
2906 {
2907  float Amin, Amax, Bmin, Bmax;
2908 
2909  if (!A) {
2910  SDL_InvalidParamError("A");
2911  return SDL_FALSE;
2912  }
2913 
2914  if (!B) {
2915  SDL_InvalidParamError("B");
2916  return SDL_FALSE;
2917  }
2918 
2919  /* Special cases for empty rects */
2920  if (SDL_FRectEmpty(A) || SDL_FRectEmpty(B)) {
2921  return SDL_FALSE;
2922  }
2923 
2924  /* Horizontal intersection */
2925  Amin = A->x;
2926  Amax = Amin + A->w;
2927  Bmin = B->x;
2928  Bmax = Bmin + B->w;
2929  if (Bmin > Amin)
2930  Amin = Bmin;
2931  if (Bmax < Amax)
2932  Amax = Bmax;
2933  if (Amax <= Amin)
2934  return SDL_FALSE;
2935 
2936  /* Vertical intersection */
2937  Amin = A->y;
2938  Amax = Amin + A->h;
2939  Bmin = B->y;
2940  Bmax = Bmin + B->h;
2941  if (Bmin > Amin)
2942  Amin = Bmin;
2943  if (Bmax < Amax)
2944  Amax = Bmax;
2945  if (Amax <= Amin)
2946  return SDL_FALSE;
2947 
2948  return SDL_TRUE;
2949 }
2950 
2951 int
2953  const SDL_Rect * srcrect, const SDL_Rect * dstrect)
2954 {
2955  SDL_FRect dstfrect;
2956  SDL_FRect *pdstfrect = NULL;
2957  if (dstrect) {
2958  dstfrect.x = (float) dstrect->x;
2959  dstfrect.y = (float) dstrect->y;
2960  dstfrect.w = (float) dstrect->w;
2961  dstfrect.h = (float) dstrect->h;
2962  pdstfrect = &dstfrect;
2963  }
2964  return SDL_RenderCopyF(renderer, texture, srcrect, pdstfrect);
2965 }
2966 
2967 int
2969  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
2970 {
2971  SDL_Rect real_srcrect;
2972  SDL_FRect real_dstrect;
2973  SDL_Rect r;
2974  int retval;
2975 
2978 
2979  if (renderer != texture->renderer) {
2980  return SDL_SetError("Texture was not created with this renderer");
2981  }
2982 
2983  /* Don't draw while we're hidden */
2984  if (renderer->hidden) {
2985  return 0;
2986  }
2987 
2988  real_srcrect.x = 0;
2989  real_srcrect.y = 0;
2990  real_srcrect.w = texture->w;
2991  real_srcrect.h = texture->h;
2992  if (srcrect) {
2993  if (!SDL_IntersectRect(srcrect, &real_srcrect, &real_srcrect)) {
2994  return 0;
2995  }
2996  }
2997 
2998  SDL_zero(r);
3000  real_dstrect.x = 0.0f;
3001  real_dstrect.y = 0.0f;
3002  real_dstrect.w = (float) r.w;
3003  real_dstrect.h = (float) r.h;
3004  if (dstrect) {
3005  if (!SDL_HasIntersectionF(dstrect, &real_dstrect)) {
3006  return 0;
3007  }
3008  real_dstrect = *dstrect;
3009  }
3010 
3011  if (texture->native) {
3012  texture = texture->native;
3013  }
3014 
3015  real_dstrect.x *= renderer->scale.x;
3016  real_dstrect.y *= renderer->scale.y;
3017  real_dstrect.w *= renderer->scale.x;
3018  real_dstrect.h *= renderer->scale.y;
3019 
3020  texture->last_command_generation = renderer->render_command_generation;
3021 
3022  retval = QueueCmdCopy(renderer, texture, &real_srcrect, &real_dstrect);
3024 }
3025 
3026 int
3028  const SDL_Rect * srcrect, const SDL_Rect * dstrect,
3029  const double angle, const SDL_Point *center, const SDL_RendererFlip flip)
3030 {
3031  SDL_FRect dstfrect;
3032  SDL_FRect *pdstfrect = NULL;
3033  SDL_FPoint fcenter;
3034  SDL_FPoint *pfcenter = NULL;
3035 
3036  if (dstrect) {
3037  dstfrect.x = (float) dstrect->x;
3038  dstfrect.y = (float) dstrect->y;
3039  dstfrect.w = (float) dstrect->w;
3040  dstfrect.h = (float) dstrect->h;
3041  pdstfrect = &dstfrect;
3042  }
3043 
3044  if (center) {
3045  fcenter.x = (float) center->x;
3046  fcenter.y = (float) center->y;
3047  pfcenter = &fcenter;
3048  }
3049 
3050  return SDL_RenderCopyExF(renderer, texture, srcrect, pdstfrect, angle, pfcenter, flip);
3051 }
3052 
3053 int
3055  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
3056  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
3057 {
3058  SDL_Rect real_srcrect;
3059  SDL_FRect real_dstrect;
3060  SDL_FPoint real_center;
3061  int retval;
3062 
3063  if (flip == SDL_FLIP_NONE && (int)(angle/360) == angle/360) { /* fast path when we don't need rotation or flipping */
3064  return SDL_RenderCopyF(renderer, texture, srcrect, dstrect);
3065  }
3066 
3069 
3070  if (renderer != texture->renderer) {
3071  return SDL_SetError("Texture was not created with this renderer");
3072  }
3073  if (!renderer->QueueCopyEx) {
3074  return SDL_SetError("Renderer does not support RenderCopyEx");
3075  }
3076 
3077  /* Don't draw while we're hidden */
3078  if (renderer->hidden) {
3079  return 0;
3080  }
3081 
3082  real_srcrect.x = 0;
3083  real_srcrect.y = 0;
3084  real_srcrect.w = texture->w;
3085  real_srcrect.h = texture->h;
3086  if (srcrect) {
3087  if (!SDL_IntersectRect(srcrect, &real_srcrect, &real_srcrect)) {
3088  return 0;
3089  }
3090  }
3091 
3092  /* We don't intersect the dstrect with the viewport as RenderCopy does because of potential rotation clipping issues... TODO: should we? */
3093  if (dstrect) {
3094  real_dstrect = *dstrect;
3095  } else {
3096  SDL_Rect r;
3097  SDL_zero(r);
3099  real_dstrect.x = 0.0f;
3100  real_dstrect.y = 0.0f;
3101  real_dstrect.w = (float) r.w;
3102  real_dstrect.h = (float) r.h;
3103  }
3104 
3105  if (texture->native) {
3106  texture = texture->native;
3107  }
3108 
3109  if (center) {
3110  real_center = *center;
3111  } else {
3112  real_center.x = real_dstrect.w / 2.0f;
3113  real_center.y = real_dstrect.h / 2.0f;
3114  }
3115 
3116  real_dstrect.x *= renderer->scale.x;
3117  real_dstrect.y *= renderer->scale.y;
3118  real_dstrect.w *= renderer->scale.x;
3119  real_dstrect.h *= renderer->scale.y;
3120 
3121  real_center.x *= renderer->scale.x;
3122  real_center.y *= renderer->scale.y;
3123 
3124  texture->last_command_generation = renderer->render_command_generation;
3125 
3126  retval = QueueCmdCopyEx(renderer, texture, &real_srcrect, &real_dstrect, angle, &real_center, flip);
3128 }
3129 
3130 int
3132  Uint32 format, void * pixels, int pitch)
3133 {
3134  SDL_Rect real_rect;
3135 
3137 
3138  if (!renderer->RenderReadPixels) {
3139  return SDL_Unsupported();
3140  }
3141 
3142  FlushRenderCommands(renderer); /* we need to render before we read the results. */
3143 
3144  if (!format) {
3146  }
3147 
3148  real_rect.x = renderer->viewport.x;
3149  real_rect.y = renderer->viewport.y;
3150  real_rect.w = renderer->viewport.w;
3151  real_rect.h = renderer->viewport.h;
3152  if (rect) {
3153  if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
3154  return 0;
3155  }
3156  if (real_rect.y > rect->y) {
3157  pixels = (Uint8 *)pixels + pitch * (real_rect.y - rect->y);
3158  }
3159  if (real_rect.x > rect->x) {
3160  int bpp = SDL_BYTESPERPIXEL(format);
3161  pixels = (Uint8 *)pixels + bpp * (real_rect.x - rect->x);
3162  }
3163  }
3164 
3165  return renderer->RenderReadPixels(renderer, &real_rect,
3166  format, pixels, pitch);
3167 }
3168 
3169 void
3171 {
3173 
3174  FlushRenderCommands(renderer); /* time to send everything to the GPU! */
3175 
3176  /* Don't present while we're hidden */
3177  if (renderer->hidden) {
3178  return;
3179  }
3181 }
3182 
3183 void
3185 {
3187 
3189 
3190  renderer = texture->renderer;
3191  if (texture == renderer->target) {
3192  SDL_SetRenderTarget(renderer, NULL); /* implies command queue flush */
3193  } else {
3195  }
3196 
3197  texture->magic = NULL;
3198 
3199  if (texture->next) {
3200  texture->next->prev = texture->prev;
3201  }
3202  if (texture->prev) {
3203  texture->prev->next = texture->next;
3204  } else {
3206  }
3207 
3208  if (texture->native) {
3209  SDL_DestroyTexture(texture->native);
3210  }
3211 #if SDL_HAVE_YUV
3212  if (texture->yuv) {
3214  }
3215 #endif
3216  SDL_free(texture->pixels);
3217 
3219 
3220  SDL_FreeSurface(texture->locked_surface);
3221  texture->locked_surface = NULL;
3222 
3223  SDL_free(texture);
3224 }
3225 
3226 void
3228 {
3229  SDL_RenderCommand *cmd;
3230 
3232 
3234 
3237  cmd = renderer->render_commands;
3238  } else {
3240  }
3241 
3245 
3246  while (cmd != NULL) {
3247  SDL_RenderCommand *next = cmd->next;
3248  SDL_free(cmd);
3249  cmd = next;
3250  }
3251 
3253 
3254  /* Free existing textures for this renderer */
3255  while (renderer->textures) {
3256  SDL_Texture *tex = renderer->textures; (void) tex;
3258  SDL_assert(tex != renderer->textures); /* satisfy static analysis. */
3259  }
3260 
3261  if (renderer->window) {
3263  }
3264 
3265  /* It's no longer magical... */
3266  renderer->magic = NULL;
3267 
3268  /* Free the target mutex */
3271 
3272  /* Free the renderer instance */
3274 }
3275 
3276 int SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh)
3277 {
3279 
3281  renderer = texture->renderer;
3282  if (texture->native) {
3283  return SDL_GL_BindTexture(texture->native, texw, texh);
3284  } else if (renderer && renderer->GL_BindTexture) {
3285  FlushRenderCommandsIfTextureNeeded(texture); /* in case the app is going to mess with it. */
3286  return renderer->GL_BindTexture(renderer, texture, texw, texh);
3287  } else {
3288  return SDL_Unsupported();
3289  }
3290 }
3291 
3293 {
3295 
3297  renderer = texture->renderer;
3298  if (texture->native) {
3299  return SDL_GL_UnbindTexture(texture->native);
3300  } else if (renderer && renderer->GL_UnbindTexture) {
3301  FlushRenderCommandsIfTextureNeeded(texture); /* in case the app messed with it. */
3303  }
3304 
3305  return SDL_Unsupported();
3306 }
3307 
3308 void *
3310 {
3312 
3313  if (renderer->GetMetalLayer) {
3314  FlushRenderCommands(renderer); /* in case the app is going to mess with it. */
3315  return renderer->GetMetalLayer(renderer);
3316  }
3317  return NULL;
3318 }
3319 
3320 void *
3322 {
3324 
3326  FlushRenderCommands(renderer); /* in case the app is going to mess with it. */
3328  }
3329  return NULL;
3330 }
3331 
3332 static SDL_BlendMode
3334 {
3336  return SDL_BLENDMODE_NONE;
3337  }
3339  return SDL_BLENDMODE_BLEND;
3340  }
3342  return SDL_BLENDMODE_ADD;
3343  }
3345  return SDL_BLENDMODE_MOD;
3346  }
3348  return SDL_BLENDMODE_MUL;
3349  }
3350  return blendMode;
3351 }
3352 
3353 static SDL_BlendMode
3355 {
3356  if (blendMode == SDL_BLENDMODE_NONE) {
3357  return SDL_BLENDMODE_NONE_FULL;
3358  }
3359  if (blendMode == SDL_BLENDMODE_BLEND) {
3360  return SDL_BLENDMODE_BLEND_FULL;
3361  }
3362  if (blendMode == SDL_BLENDMODE_ADD) {
3363  return SDL_BLENDMODE_ADD_FULL;
3364  }
3365  if (blendMode == SDL_BLENDMODE_MOD) {
3366  return SDL_BLENDMODE_MOD_FULL;
3367  }
3368  if (blendMode == SDL_BLENDMODE_MUL) {
3369  return SDL_BLENDMODE_MUL_FULL;
3370  }
3371  return blendMode;
3372 }
3373 
3376  SDL_BlendOperation colorOperation,
3377  SDL_BlendFactor srcAlphaFactor, SDL_BlendFactor dstAlphaFactor,
3378  SDL_BlendOperation alphaOperation)
3379 {
3380  SDL_BlendMode blendMode = SDL_COMPOSE_BLENDMODE(srcColorFactor, dstColorFactor, colorOperation,
3381  srcAlphaFactor, dstAlphaFactor, alphaOperation);
3383 }
3384 
3387 {
3389  return (SDL_BlendFactor)(((Uint32)blendMode >> 4) & 0xF);
3390 }
3391 
3394 {
3396  return (SDL_BlendFactor)(((Uint32)blendMode >> 8) & 0xF);
3397 }
3398 
3401 {
3403  return (SDL_BlendOperation)(((Uint32)blendMode >> 0) & 0xF);
3404 }
3405 
3408 {
3410  return (SDL_BlendFactor)(((Uint32)blendMode >> 20) & 0xF);
3411 }
3412 
3415 {
3417  return (SDL_BlendFactor)(((Uint32)blendMode >> 24) & 0xF);
3418 }
3419 
3422 {
3424  return (SDL_BlendOperation)(((Uint32)blendMode >> 16) & 0xF);
3425 }
3426 
3427 /* vi: set ts=4 sw=4 expandtab: */
void Android_ActivityMutex_Unlock(void)
void Android_ActivityMutex_Lock_Running(void)
#define SDL_assert(condition)
Definition: SDL_assert.h:171
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
Definition: SDL_blendmode.h:66
SDL_BlendFactor
The normalized factor used to multiply pixel components.
Definition: SDL_blendmode.h:79
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:41
@ SDL_BLENDMODE_NONE
Definition: SDL_blendmode.h:42
@ SDL_BLENDMODE_ADD
Definition: SDL_blendmode.h:47
@ SDL_BLENDMODE_BLEND
Definition: SDL_blendmode.h:44
@ SDL_BLENDMODE_MUL
Definition: SDL_blendmode.h:53
@ SDL_BLENDMODE_MOD
Definition: SDL_blendmode.h:50
#define SDL_SetError
#define SDL_GetWindowSize
#define SDL_GetSurfaceBlendMode
#define SDL_GetCurrentVideoDriver
#define SDL_FreeFormat
#define SDL_GetWindowData
#define SDL_GetSurfaceAlphaMod
#define SDL_CreateWindow
#define SDL_GetWindowFlags
#define SDL_floor
#define SDL_GetWindowPixelFormat
#define SDL_DelEventWatch
#define SDL_LockMutex
#define SDL_AllocFormat
#define SDL_AddEventWatch
#define SDL_malloc
#define SDL_truncf
#define SDL_realloc
#define SDL_strcasecmp
#define SDL_fabs
#define SDL_CreateMutex
#define SDL_UnlockSurface
#define SDL_free
#define SDL_HasColorKey
#define SDL_memcmp
#define SDL_GetWindowFromID
#define SDL_SetWindowData
#define SDL_GetHintBoolean
#define SDL_LockSurface
#define SDL_GetSurfaceColorMod
#define SDL_memcpy
#define SDL_FreeSurface
#define SDL_DestroyMutex
#define SDL_atoi
#define SDL_Log
#define SDL_LogInfo
#define SDL_IntersectRect
#define SDL_CreateRGBSurfaceWithFormatFrom
#define SDL_calloc
#define SDL_GetHint
#define SDL_ConvertPixels
#define SDL_UnlockMutex
#define SDL_ceil
#define SDL_ConvertSurface
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
#define SDL_OutOfMemory()
Definition: SDL_error.h:88
#define SDL_Unsupported()
Definition: SDL_error.h:89
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:90
@ SDL_MOUSEMOTION
Definition: SDL_events.h:107
@ SDL_FINGERMOTION
Definition: SDL_events.h:136
@ SDL_MOUSEBUTTONUP
Definition: SDL_events.h:109
@ SDL_WINDOWEVENT
Definition: SDL_events.h:94
@ SDL_FINGERUP
Definition: SDL_events.h:135
@ SDL_MOUSEBUTTONDOWN
Definition: SDL_events.h:108
@ SDL_FINGERDOWN
Definition: SDL_events.h:134
#define SDL_HINT_RENDER_SCALE_QUALITY
A variable controlling the scaling quality.
Definition: SDL_hints.h:143
#define SDL_HINT_RENDER_DRIVER
A variable specifying which render driver to use.
Definition: SDL_hints.h:85
#define SDL_HINT_RENDER_LOGICAL_SIZE_MODE
A variable controlling the scaling policy for SDL_RenderSetLogicalSize.
Definition: SDL_hints.h:131
#define SDL_HINT_MOUSE_RELATIVE_SCALING
A variable controlling whether relative mouse motion is affected by renderer scaling.
Definition: SDL_hints.h:326
#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
#define SDL_HINT_RENDER_BATCHING
A variable controlling whether the 2D render API is compatible or efficient.
Definition: SDL_hints.h:1302
#define SDLCALL
Definition: SDL_internal.h:49
#define SDL_small_alloc(type, count, pisstack)
Definition: SDL_internal.h:39
#define SDL_small_free(ptr, isstack)
Definition: SDL_internal.h:40
@ SDL_LOG_CATEGORY_RENDER
Definition: SDL_log.h:72
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
GLboolean GLboolean GLboolean b
struct _cl_event * event
GLfixed GLfixed GLint GLint GLfixed points
GLenum GLenum GLenum GLenum GLenum scale
GLfixed GLfixed GLfixed y2
GLfixed y1
GLuint color
GLuint GLfloat GLfloat GLfloat x1
GLintptr offset
GLuint index
GLboolean GLboolean GLboolean GLboolean a
GLfixed GLfixed x2
GLboolean GLboolean g
GLfloat angle
GLuint GLint GLboolean GLint GLenum access
GLbitfield flags
GLboolean enable
GLenum GLenum GLuint texture
GLfloat GLfloat GLfloat alpha
GLdouble n
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
void SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel)
Definition: SDL_pixels.c:806
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:128
#define SDL_ISPIXELFORMAT_ALPHA(format)
Definition: SDL_pixels.h:154
#define SDL_ISPIXELFORMAT_INDEXED(format)
Definition: SDL_pixels.h:134
@ SDL_PIXELFORMAT_BGR888
Definition: SDL_pixels.h:253
@ SDL_PIXELFORMAT_YV12
Definition: SDL_pixels.h:286
@ SDL_PIXELFORMAT_RGB888
Definition: SDL_pixels.h:246
@ SDL_PIXELFORMAT_ABGR8888
Definition: SDL_pixels.h:263
@ SDL_PIXELFORMAT_IYUV
Definition: SDL_pixels.h:288
@ SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:257
@ SDL_PIXELFORMAT_UNKNOWN
Definition: SDL_pixels.h:173
#define SDL_ISPIXELFORMAT_FOURCC(format)
Definition: SDL_pixels.h:167
void SDL_DestroyTexture(SDL_Texture *texture)
Destroy the specified texture.
Definition: SDL_render.c:3184
static void SDL_UnlockTextureNative(SDL_Texture *texture)
Definition: SDL_render.c:1822
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3393
int SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
Set a texture as the current rendering target.
Definition: SDL_render.c:1876
void SDL_RenderGetScale(SDL_Renderer *renderer, float *scaleX, float *scaleY)
Get the drawing scale for the current target.
Definition: SDL_render.c:2208
static const SDL_RenderDriver * render_drivers[]
Definition: SDL_render.c:82
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3386
static int QueueCmdSetDrawColor(SDL_Renderer *renderer, const Uint8 r, const Uint8 g, const Uint8 b, const Uint8 a)
Definition: SDL_render.c:370
int SDL_RenderDrawPoint(SDL_Renderer *renderer, int x, int y)
Draw a point on the current rendering target.
Definition: SDL_render.c:2289
static int QueueCmdSetViewport(SDL_Renderer *renderer)
Definition: SDL_render.c:325
int SDL_RenderCopyF(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Copy a portion of the texture to the current rendering target.
Definition: SDL_render.c:2968
static int PrepQueueCmdDraw(SDL_Renderer *renderer, const Uint8 r, const Uint8 g, const Uint8 b, const Uint8 a)
Definition: SDL_render.c:416
int SDL_RenderClear(SDL_Renderer *renderer)
Clear the current rendering target with the drawing color.
Definition: SDL_render.c:2276
void * SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset)
Definition: SDL_render.c:262
int SDL_RenderDrawLineF(SDL_Renderer *renderer, float x1, float y1, float x2, float y2)
Draw a line on the current rendering target.
Definition: SDL_render.c:2458
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:1633
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:2221
int SDL_QueryTexture(SDL_Texture *texture, Uint32 *format, int *access, int *w, int *h)
Query the attributes of a texture.
Definition: SDL_render.c:1309
void SDL_DestroyRenderer(SDL_Renderer *renderer)
Destroy the rendering context for a window and free associated textures.
Definition: SDL_render.c:3227
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3414
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3407
void SDL_UnlockTexture(SDL_Texture *texture)
Unlock a texture, uploading the changes to video memory, if needed. If SDL_LockTextureToSurface() was...
Definition: SDL_render.c:1843
int SDL_GetNumRenderDrivers(void)
Get the number of 2D rendering drivers available for the current display.
Definition: SDL_render.c:552
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:1066
static SDL_RenderCommand * PrepQueueCmdDrawTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_RenderCommandType cmdtype)
Definition: SDL_render.c:496
#define SDL_WINDOWRENDERDATA
Definition: SDL_render.c:35
void * SDL_RenderGetMetalCommandEncoder(SDL_Renderer *renderer)
Get the Metal command encoder for the current frame.
Definition: SDL_render.c:3321
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:3131
int SDL_RenderDrawLinesF(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Draw a series of connected lines on the current rendering target.
Definition: SDL_render.c:2622
void SDL_RenderPresent(SDL_Renderer *renderer)
Update the screen with rendering performed.
Definition: SDL_render.c:3170
int SDL_GetTextureBlendMode(SDL_Texture *texture, SDL_BlendMode *blendMode)
Get the blend mode used for texture copy operations.
Definition: SDL_render.c:1413
static int QueueCmdSetClipRect(SDL_Renderer *renderer)
Definition: SDL_render.c:348
int SDL_GetTextureScaleMode(SDL_Texture *texture, SDL_ScaleMode *scaleMode)
Get the scale mode used for texture scale operations.
Definition: SDL_render.c:1440
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:1349
int SDL_GL_UnbindTexture(SDL_Texture *texture)
Unbind a texture from the current OpenGL/ES/ES2 context.
Definition: SDL_render.c:3292
int SDL_RenderSetViewport(SDL_Renderer *renderer, const SDL_Rect *rect)
Set the drawing area for rendering on the current target.
Definition: SDL_render.c:2122
SDL_Texture * SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *surface)
Create a texture from an existing surface.
Definition: SDL_render.c:1165
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:1581
static int RenderDrawPointsWithRectsF(SDL_Renderer *renderer, const SDL_FPoint *fpoints, const int count)
Definition: SDL_render.c:2377
void SDL_RenderGetViewport(SDL_Renderer *renderer, SDL_Rect *rect)
Get the drawing area for the current target.
Definition: SDL_render.c:2144
int SDL_RenderDrawPointF(SDL_Renderer *renderer, float x, float y)
Draw a point on the current rendering target.
Definition: SDL_render.c:2298
#define CHECK_TEXTURE_MAGIC(texture, retval)
Definition: SDL_render.c:44
SDL_bool SDL_RenderIsClipEnabled(SDL_Renderer *renderer)
Get whether clipping is enabled on the given renderer.
Definition: SDL_render.c:2191
int SDL_SetRenderDrawBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode)
Set the blend mode used for drawing operations (Fill and Line).
Definition: SDL_render.c:2255
SDL_bool SDL_RenderTargetSupported(SDL_Renderer *renderer)
Determines whether a window supports the use of render targets.
Definition: SDL_render.c:1867
static int FlushRenderCommandsIfTextureNeeded(SDL_Texture *texture)
Definition: SDL_render.c:239
void SDL_RenderGetClipRect(SDL_Renderer *renderer, SDL_Rect *rect)
Get the clip rectangle for the current target.
Definition: SDL_render.c:2178
int SDL_GetRendererInfo(SDL_Renderer *renderer, SDL_RendererInfo *info)
Get information about a rendering context.
Definition: SDL_render.c:966
int SDL_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count)
Draw multiple points on the current rendering target.
Definition: SDL_render.c:2334
int SDL_RenderSetClipRect(SDL_Renderer *renderer, const SDL_Rect *rect)
Set the clip rectangle for the current target.
Definition: SDL_render.c:2157
static int QueueCmdCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
Definition: SDL_render.c:532
int SDL_RenderDrawPointsF(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Draw multiple points on the current rendering target.
Definition: SDL_render.c:2404
static int UpdateLogicalSize(SDL_Renderer *renderer)
Definition: SDL_render.c:1962
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:2770
SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:3421
int SDL_GetRendererOutputSize(SDL_Renderer *renderer, int *w, int *h)
Get the output size in pixels of a rendering context.
Definition: SDL_render.c:975
int SDL_RenderSetIntegerScale(SDL_Renderer *renderer, SDL_bool enable)
Set whether to force integer scales for resolution-independent rendering.
Definition: SDL_render.c:2104
int SDL_SetTextureAlphaMod(SDL_Texture *texture, Uint8 alpha)
Set an additional alpha value used in render copy operations.
Definition: SDL_render.c:1367
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:2816
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:752
void * SDL_RenderGetMetalLayer(SDL_Renderer *renderer)
Get the CAMetalLayer associated with the given Metal renderer.
Definition: SDL_render.c:3309
static int SDL_RendererEventWatch(void *userdata, SDL_Event *event)
Definition: SDL_render.c:587
static SDL_BlendMode SDL_GetLongBlendMode(SDL_BlendMode blendMode)
Definition: SDL_render.c:3354
static Uint32 GetClosestSupportedFormat(SDL_Renderer *renderer, Uint32 format)
Definition: SDL_render.c:1024
static SDL_bool SDL_HasIntersectionF(const SDL_FRect *A, const SDL_FRect *B)
Definition: SDL_render.c:2905
int SDL_RenderCopyExF(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
Copy a portion of the source texture to the current rendering target, rotating it by angle around the...
Definition: SDL_render.c:3054
SDL_bool SDL_RenderGetIntegerScale(SDL_Renderer *renderer)
Get whether integer scales are forced for resolution-independent rendering.
Definition: SDL_render.c:2114
int SDL_SetTextureScaleMode(SDL_Texture *texture, SDL_ScaleMode scaleMode)
Set the scale mode used for texture scale operations.
Definition: SDL_render.c:1424
int SDL_RenderSetScale(SDL_Renderer *renderer, float scaleX, float scaleY)
Set the drawing scale for rendering on the current target.
Definition: SDL_render.c:2198
static void GetWindowViewportValues(SDL_Renderer *renderer, int *logical_w, int *logical_h, SDL_Rect *viewport, SDL_FPoint *scale)
Definition: SDL_render.c:576
#define SDL_COMPOSE_BLENDMODE(srcColorFactor, dstColorFactor, colorOperation, srcAlphaFactor, dstAlphaFactor, alphaOperation)
Definition: SDL_render.c:52
static int SDL_UpdateTextureNative(SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_render.c:1499
static int FlushRenderCommands(SDL_Renderer *renderer)
Definition: SDL_render.c:208
static int RenderDrawPointsWithRects(SDL_Renderer *renderer, const SDL_Point *points, const int count)
Definition: SDL_render.c:2307
#define SDL_BLENDMODE_NONE_FULL
Definition: SDL_render.c:61
static SDL_bool IsSupportedFormat(SDL_Renderer *renderer, Uint32 format)
Definition: SDL_render.c:1011
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:1330
static SDL_bool IsSupportedBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode)
Definition: SDL_render.c:993
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:3276
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:2234
int SDL_GetRenderDrawBlendMode(SDL_Renderer *renderer, SDL_BlendMode *blendMode)
Get the blend mode used for drawing operations.
Definition: SDL_render.c:2267
SDL_Texture * SDL_GetRenderTarget(SDL_Renderer *renderer)
Get the current render target or NULL for the default render target.
Definition: SDL_render.c:1956
static SDL_INLINE int FlushRenderCommandsIfNotBatching(SDL_Renderer *renderer)
Definition: SDL_render.c:250
int SDL_RenderFlush(SDL_Renderer *renderer)
Force the rendering context to flush any pending commands to the underlying rendering API.
Definition: SDL_render.c:256
static int QueueCmdDrawPoints(SDL_Renderer *renderer, const SDL_FPoint *points, const int count)
Definition: SDL_render.c:454
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:1540
#define SDL_BLENDMODE_MOD_FULL
Definition: SDL_render.c:73
static int QueueCmdClear(SDL_Renderer *renderer)
Definition: SDL_render.c:399
#define SDL_BLENDMODE_ADD_FULL
Definition: SDL_render.c:69
static SDL_RenderCommand * PrepQueueCmdDrawSolid(SDL_Renderer *renderer, const SDL_RenderCommandType cmdtype)
Definition: SDL_render.c:432
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:2714
static int SDL_UpdateTextureYUV(SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_render.c:1452
int SDL_LockTextureToSurface(SDL_Texture *texture, const SDL_Rect *rect, SDL_Surface **surface)
Lock a portion of the texture for write-only pixel access. Expose it as a SDL surface.
Definition: SDL_render.c:1762
static int RenderDrawLinesWithRectsF(SDL_Renderer *renderer, const SDL_FPoint *points, const int count)
Definition: SDL_render.c:2524
void SDL_RenderGetLogicalSize(SDL_Renderer *renderer, int *w, int *h)
Get device independent resolution for rendering.
Definition: SDL_render.c:2091
int SDL_RenderFillRectF(SDL_Renderer *renderer, const SDL_FRect *rect)
Fill a rectangle on the current rendering target with the drawing color.
Definition: SDL_render.c:2795
static SDL_BlendMode SDL_GetShortBlendMode(SDL_BlendMode blendMode)
Definition: SDL_render.c:3333
int SDL_RenderDrawRectF(SDL_Renderer *renderer, const SDL_FRect *rect)
Draw a rectangle on the current rendering target.
Definition: SDL_render.c:2682
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:3400
static int SDL_LockTextureYUV(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_render.c:1702
SDL_Renderer * SDL_CreateSoftwareRenderer(SDL_Surface *surface)
Create a 2D software rendering context for a surface.
Definition: SDL_render.c:933
#define CHECK_RENDERER_MAGIC(renderer, retval)
Definition: SDL_render.c:37
static int QueueCmdDrawLines(SDL_Renderer *renderer, const SDL_FPoint *points, const int count)
Definition: SDL_render.c:468
static int RenderDrawLinesWithRects(SDL_Renderer *renderer, const SDL_Point *points, const int count)
Definition: SDL_render.c:2469
int SDL_RenderDrawRectsF(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
Draw some number of rectangles on the current rendering target.
Definition: SDL_render.c:2742
static int QueueCmdCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Definition: SDL_render.c:518
int SDL_GetTextureAlphaMod(SDL_Texture *texture, Uint8 *alpha)
Get the additional alpha value used in render copy operations.
Definition: SDL_render.c:1384
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:2952
static SDL_INLINE void VerifyDrawQueueFunctions(const SDL_Renderer *renderer)
Definition: SDL_render.c:772
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:3375
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:2447
int SDL_SetTextureBlendMode(SDL_Texture *texture, SDL_BlendMode blendMode)
Set the blend mode used for texture copy operations.
Definition: SDL_render.c:1395
SDL_Renderer * SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags)
Create a 2D rendering context for a window.
Definition: SDL_render.c:786
#define SDL_BLENDMODE_MUL_FULL
Definition: SDL_render.c:77
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:2579
static SDL_RenderCommand * AllocateRenderCommand(SDL_Renderer *renderer)
Definition: SDL_render.c:296
static SDL_INLINE void DebugLogRenderCommands(const SDL_RenderCommand *cmd)
Definition: SDL_render.c:117
static void SDL_UnlockTextureYUV(SDL_Texture *texture)
Definition: SDL_render.c:1800
static SDL_ScaleMode SDL_GetScaleMode(void)
Definition: SDL_render.c:1050
int SDL_RenderFillRectsF(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
Fill some number of rectangles on the current rendering target with the drawing color.
Definition: SDL_render.c:2857
int SDL_RenderSetLogicalSize(SDL_Renderer *renderer, int w, int h)
Set device independent resolution for rendering.
Definition: SDL_render.c:2071
static int QueueCmdFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, const int count)
Definition: SDL_render.c:482
#define SDL_BLENDMODE_BLEND_FULL
Definition: SDL_render.c:65
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:1722
int SDL_RenderDrawRect(SDL_Renderer *renderer, const SDL_Rect *rect)
Draw a rectangle on the current rendering target.
Definition: SDL_render.c:2665
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:3027
SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r)
Definition: SDL_render.c:2898
static int SDL_LockTextureNative(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_render.c:1710
int SDL_GetRenderDriverInfo(int index, SDL_RendererInfo *info)
Get information about a specific 2D rendering driver for the current display.
Definition: SDL_render.c:562
SDL_Renderer * SDL_GetRenderer(SDL_Window *window)
Get the renderer associated with a window.
Definition: SDL_render.c:960
static char renderer_magic
Definition: SDL_render.c:113
static char texture_magic
Definition: SDL_render.c:114
@ SDL_RENDERER_PRESENTVSYNC
Definition: SDL_render.h:69
@ SDL_RENDERER_TARGETTEXTURE
Definition: SDL_render.h:71
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:122
@ SDL_FLIP_NONE
Definition: SDL_render.h:123
@ SDL_TEXTUREACCESS_STATIC
Definition: SDL_render.h:103
@ SDL_TEXTUREACCESS_STREAMING
Definition: SDL_render.h:104
@ SDL_TEXTUREACCESS_TARGET
Definition: SDL_render.h:105
@ SDL_TEXTUREMODULATE_ALPHA
Definition: SDL_render.h:115
@ SDL_TEXTUREMODULATE_COLOR
Definition: SDL_render.h:114
SDL_ScaleMode
The scaling mode for a texture.
Definition: SDL_render.h:92
@ SDL_ScaleModeLinear
Definition: SDL_render.h:94
@ SDL_ScaleModeBest
Definition: SDL_render.h:95
@ SDL_ScaleModeNearest
Definition: SDL_render.h:93
SDL_Renderer * SW_CreateRendererForSurface(SDL_Surface *surface)
#define SDL_zero(x)
Definition: SDL_stdinc.h:426
SDL_bool
Definition: SDL_stdinc.h:168
@ SDL_TRUE
Definition: SDL_stdinc.h:170
@ SDL_FALSE
Definition: SDL_stdinc.h:169
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:121
uint8_t Uint8
Definition: SDL_stdinc.h:185
int32_t Sint32
Definition: SDL_stdinc.h:203
#define SDL_min(x, y)
Definition: SDL_stdinc.h:412
uint32_t Uint32
Definition: SDL_stdinc.h:209
#define SDL_max(x, y)
Definition: SDL_stdinc.h:413
#define SDL_MUSTLOCK(S)
Definition: SDL_surface.h:62
SDL_RenderDriver PSP_RenderDriver
SDL_RenderDriver METAL_RenderDriver
SDL_RenderDriver DirectFB_RenderDriver
SDL_RenderDriver GLES2_RenderDriver
SDL_RenderDriver GL_RenderDriver
SDL_RenderDriver SW_RenderDriver
SDL_RenderDriver D3D_RenderDriver
SDL_RenderDriver GLES_RenderDriver
SDL_RenderDriver D3D11_RenderDriver
SDL_RenderCommandType
Definition: SDL_sysrender.h:67
@ SDL_RENDERCMD_SETCLIPRECT
Definition: SDL_sysrender.h:70
@ SDL_RENDERCMD_DRAW_LINES
Definition: SDL_sysrender.h:74
@ SDL_RENDERCMD_SETVIEWPORT
Definition: SDL_sysrender.h:69
@ SDL_RENDERCMD_DRAW_POINTS
Definition: SDL_sysrender.h:73
@ SDL_RENDERCMD_NO_OP
Definition: SDL_sysrender.h:68
@ SDL_RENDERCMD_FILL_RECTS
Definition: SDL_sysrender.h:75
@ SDL_RENDERCMD_COPY
Definition: SDL_sysrender.h:76
@ SDL_RENDERCMD_CLEAR
Definition: SDL_sysrender.h:72
@ SDL_RENDERCMD_SETDRAWCOLOR
Definition: SDL_sysrender.h:71
@ SDL_RENDERCMD_COPY_EX
Definition: SDL_sysrender.h:77
#define SDL_WINDOWPOS_UNDEFINED
Definition: SDL_video.h:130
@ SDL_WINDOW_MINIMIZED
Definition: SDL_video.h:105
@ SDL_WINDOW_HIDDEN
Definition: SDL_video.h:102
@ SDL_WINDOWEVENT_HIDDEN
Definition: SDL_video.h:150
@ SDL_WINDOWEVENT_SHOWN
Definition: SDL_video.h:149
@ SDL_WINDOWEVENT_MINIMIZED
Definition: SDL_video.h:159
@ SDL_WINDOWEVENT_MAXIMIZED
Definition: SDL_video.h:160
@ SDL_WINDOWEVENT_SIZE_CHANGED
Definition: SDL_video.h:156
@ SDL_WINDOWEVENT_RESTORED
Definition: SDL_video.h:161
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
void SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture *swdata)
Definition: SDL_yuv_sw.c:405
SDL_SW_YUVTexture * SDL_SW_CreateYUVTexture(Uint32 format, int w, int h)
Definition: SDL_yuv_sw.c:32
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:335
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:248
int SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_yuv_sw.c:140
int SDL_SW_LockYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_yuv_sw.c:303
#define NULL
Definition: begin_code.h:163
#define SDL_INLINE
Definition: begin_code.h:130
#define SDL_FORCE_INLINE
Definition: begin_code.h:143
EGLSurface surface
Definition: eglext.h:248
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
EGLSurface EGLint * rects
Definition: eglext.h:282
GLfloat GLfloat GLfloat GLfloat GLfloat maxY
Definition: gl2ext.h:446
GLfloat minY
Definition: gl2ext.h:446
GLfloat GLfloat GLfloat GLfloat maxX
Definition: gl2ext.h:446
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst numbytes
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
The structure that defines a point (floating point)
Definition: SDL_rect.h:61
float x
Definition: SDL_rect.h:62
float y
Definition: SDL_rect.h:63
A rectangle, with the origin at the upper left (floating point).
Definition: SDL_rect.h:88
float h
Definition: SDL_rect.h:92
float x
Definition: SDL_rect.h:89
float w
Definition: SDL_rect.h:91
float y
Definition: SDL_rect.h:90
SDL_Palette * palette
Definition: SDL_pixels.h:327
The structure that defines a point (integer)
Definition: SDL_rect.h:49
int x
Definition: SDL_rect.h:50
int y
Definition: SDL_rect.h:51
A rectangle, with the origin at the upper left (integer).
Definition: SDL_rect.h:78
int h
Definition: SDL_rect.h:80
int w
Definition: SDL_rect.h:80
int y
Definition: SDL_rect.h:79
int x
Definition: SDL_rect.h:79
struct SDL_RenderCommand::@38::@42 color
struct SDL_RenderCommand * next
struct SDL_RenderCommand::@38::@39 viewport
struct SDL_RenderCommand::@38::@41 draw
SDL_RenderCommandType command
Definition: SDL_sysrender.h:82
union SDL_RenderCommand::@38 data
struct SDL_RenderCommand::@38::@40 cliprect
SDL_RendererInfo info
SDL_Renderer *(* CreateRenderer)(SDL_Window *window, Uint32 flags)
int(* QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
SDL_Rect last_queued_viewport
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
SDL_bool clipping_enabled
SDL_Window * window
const void * magic
SDL_Rect clip_rect_backup
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)
int(* QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
void(* SetTextureScaleMode)(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode)
SDL_RenderCommand * render_commands
SDL_Texture * textures
SDL_bool cliprect_queued
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_bool always_batch
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_bool batching
void(* DestroyRenderer)(SDL_Renderer *renderer)
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
size_t vertex_data_allocation
SDL_RenderCommand * render_commands_tail
SDL_mutex * target_mutex
SDL_Rect clip_rect
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
SDL_bool integer_scale
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
void * vertex_data
SDL_bool color_queued
void(* RenderPresent)(SDL_Renderer *renderer)
SDL_FPoint scale
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
SDL_RenderCommand * render_commands_pool
SDL_Rect viewport
int(* QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
SDL_bool hidden
int(* QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
int(* RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
int(* QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_bool viewport_queued
SDL_FPoint scale_backup
int(* QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
SDL_RendererInfo info
SDL_Rect last_queued_cliprect
Uint32 render_command_generation
size_t vertex_data_used
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_bool last_queued_cliprect_enabled
Uint32 last_queued_color
void *(* GetMetalLayer)(SDL_Renderer *renderer)
void *(* GetMetalCommandEncoder)(SDL_Renderer *renderer)
SDL_Texture * target
SDL_FPoint dpi_scale
SDL_bool clipping_enabled_backup
SDL_Rect viewport_backup
SDL_bool relative_scaling
SDL_BlendMode blendMode
int(* QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
Information on the capabilities of a render driver or context.
Definition: SDL_render.h:79
const char * name
Definition: SDL_render.h:80
int max_texture_height
Definition: SDL_render.h:85
Uint32 texture_formats[16]
Definition: SDL_render.h:83
Uint32 num_texture_formats
Definition: SDL_render.h:82
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71
void * pixels
Definition: SDL_surface.h:76
SDL_Texture * prev
Definition: SDL_sysrender.h:62
Uint32 format
Definition: SDL_sysrender.h:39
SDL_Texture * next
Definition: SDL_sysrender.h:63
SDL_Texture * native
Definition: SDL_sysrender.h:51
The type used to identify a window.
Definition: SDL_sysvideo.h:75
static SDL_Renderer * renderer
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
SDL_bool retval
int window_w
Definition: testoverlay2.c:145
int window_h
Definition: testoverlay2.c:146
SDL_Rect rect
Definition: testrelative.c:27
static SDL_Rect viewport
Definition: testviewport.c:28
General event structure.
Definition: SDL_events.h:592
typedef int(__stdcall *FARPROC)()