Bug Summary

File:render/SDL_render.c
Location:line 1005, column 5
Description:Function call argument is an uninitialized value

Annotated Source Code

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