summaryrefslogtreecommitdiff
path: root/src/contrib/SDL-3.2.20/test/testautomation_render.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/contrib/SDL-3.2.20/test/testautomation_render.c')
-rw-r--r--src/contrib/SDL-3.2.20/test/testautomation_render.c1720
1 files changed, 1720 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/test/testautomation_render.c b/src/contrib/SDL-3.2.20/test/testautomation_render.c
new file mode 100644
index 0000000..9a0503d
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/test/testautomation_render.c
@@ -0,0 +1,1720 @@
1/**
2 * Original code: automated SDL platform test written by Edgar Simo "bobbens"
3 * Extended and extensively updated by aschiffler at ferzkopp dot net
4 */
5#include <SDL3/SDL.h>
6#include <SDL3/SDL_test.h>
7#include "testautomation_images.h"
8#include "testautomation_suites.h"
9
10/* ================= Test Case Implementation ================== */
11
12#define TESTRENDER_SCREEN_W 80
13#define TESTRENDER_SCREEN_H 60
14
15
16#define RENDER_COMPARE_FORMAT SDL_PIXELFORMAT_ARGB8888
17#define RENDER_COLOR_CLEAR 0xFF000000
18#define RENDER_COLOR_GREEN 0xFF00FF00
19
20#define ALLOWABLE_ERROR_OPAQUE 0
21#define ALLOWABLE_ERROR_BLENDED 0
22
23#define CHECK_FUNC(FUNC, PARAMS) \
24{ \
25 bool result = FUNC PARAMS; \
26 if (!result) { \
27 SDLTest_AssertCheck(result, "Validate result from %s, expected: true, got: false, %s", #FUNC, SDL_GetError()); \
28 } \
29}
30
31/* Test window and renderer */
32static SDL_Window *window = NULL;
33static SDL_Renderer *renderer = NULL;
34
35/* Prototypes for helper functions */
36
37static int clearScreen(void);
38static void compare(SDL_Surface *reference, int allowable_error);
39static void compare2x(SDL_Surface *reference, int allowable_error);
40static SDL_Texture *loadTestFace(void);
41static bool isSupported(int code);
42static bool hasDrawColor(void);
43
44/**
45 * Create software renderer for tests
46 */
47static void SDLCALL InitCreateRenderer(void **arg)
48{
49 int width = 320, height = 240;
50 const char *renderer_name = NULL;
51 renderer = NULL;
52 window = SDL_CreateWindow("render_testCreateRenderer", width, height, 0);
53 SDLTest_AssertPass("SDL_CreateWindow()");
54 SDLTest_AssertCheck(window != NULL, "Check SDL_CreateWindow result");
55 if (window == NULL) {
56 return;
57 }
58
59 renderer = SDL_CreateRenderer(window, renderer_name);
60 SDLTest_AssertPass("SDL_CreateRenderer()");
61 SDLTest_AssertCheck(renderer != NULL, "Check SDL_CreateRenderer result: %s", renderer != NULL ? "success" : SDL_GetError());
62 if (renderer == NULL) {
63 SDL_DestroyWindow(window);
64 return;
65 }
66}
67
68/**
69 * Destroy renderer for tests
70 */
71static void SDLCALL CleanupDestroyRenderer(void *arg)
72{
73 if (renderer) {
74 SDL_DestroyRenderer(renderer);
75 renderer = NULL;
76 SDLTest_AssertPass("SDL_DestroyRenderer()");
77 }
78
79 if (window) {
80 SDL_DestroyWindow(window);
81 window = NULL;
82 SDLTest_AssertPass("SDL_DestroyWindow");
83 }
84}
85
86/**
87 * Tests call to SDL_GetNumRenderDrivers
88 *
89 * \sa SDL_GetNumRenderDrivers
90 */
91static int SDLCALL render_testGetNumRenderDrivers(void *arg)
92{
93 int n;
94 n = SDL_GetNumRenderDrivers();
95 SDLTest_AssertCheck(n >= 1, "Number of renderers >= 1, reported as %i", n);
96 return TEST_COMPLETED;
97}
98
99/**
100 * Tests the SDL primitives for rendering.
101 *
102 * \sa SDL_SetRenderDrawColor
103 * \sa SDL_RenderFillRect
104 * \sa SDL_RenderLine
105 *
106 */
107static int SDLCALL render_testPrimitives(void *arg)
108{
109 int ret;
110 int x, y;
111 SDL_FRect rect;
112 SDL_Surface *referenceSurface = NULL;
113 int checkFailCount1;
114 int checkFailCount2;
115
116 /* Clear surface. */
117 clearScreen();
118
119 /* Need drawcolor or just skip test. */
120 SDLTest_AssertCheck(hasDrawColor(), "hasDrawColor");
121
122 /* Draw a rectangle. */
123 rect.x = 40.0f;
124 rect.y = 0.0f;
125 rect.w = 40.0f;
126 rect.h = 80.0f;
127
128 CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 13, 73, 200, SDL_ALPHA_OPAQUE))
129 CHECK_FUNC(SDL_RenderFillRect, (renderer, &rect))
130
131 /* Draw a rectangle. */
132 rect.x = 10.0f;
133 rect.y = 10.0f;
134 rect.w = 60.0f;
135 rect.h = 40.0f;
136 CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 200, 0, 100, SDL_ALPHA_OPAQUE))
137 CHECK_FUNC(SDL_RenderFillRect, (renderer, &rect))
138
139 /* Draw some points like so:
140 * X.X.X.X..
141 * .X.X.X.X.
142 * X.X.X.X.. */
143 checkFailCount1 = 0;
144 checkFailCount2 = 0;
145 for (y = 0; y < 3; y++) {
146 for (x = y % 2; x < TESTRENDER_SCREEN_W; x += 2) {
147 ret = SDL_SetRenderDrawColor(renderer, (Uint8)(x * y), (Uint8)(x * y / 2), (Uint8)(x * y / 3), SDL_ALPHA_OPAQUE);
148 if (!ret) {
149 checkFailCount1++;
150 }
151
152 ret = SDL_RenderPoint(renderer, (float)x, (float)y);
153 if (!ret) {
154 checkFailCount2++;
155 }
156 }
157 }
158 SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetRenderDrawColor, expected: 0, got: %i", checkFailCount1);
159 SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_RenderPoint, expected: 0, got: %i", checkFailCount2);
160
161 /* Draw some lines. */
162 CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 0, 255, 0, SDL_ALPHA_OPAQUE))
163 CHECK_FUNC(SDL_RenderLine, (renderer, 0.0f, 30.0f, TESTRENDER_SCREEN_W, 30.0f))
164 CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 55, 55, 5, SDL_ALPHA_OPAQUE))
165 CHECK_FUNC(SDL_RenderLine, (renderer, 40.0f, 30.0f, 40.0f, 60.0f))
166 CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 5, 105, 105, SDL_ALPHA_OPAQUE))
167 CHECK_FUNC(SDL_RenderLine, (renderer, 0.0f, 0.0f, 29.0f, 29.0f))
168 CHECK_FUNC(SDL_RenderLine, (renderer, 29.0f, 30.0f, 0.0f, 59.0f))
169 CHECK_FUNC(SDL_RenderLine, (renderer, 79.0f, 0.0f, 50.0f, 29.0f))
170 CHECK_FUNC(SDL_RenderLine, (renderer, 79.0f, 59.0f, 50.0f, 30.0f))
171
172 /* See if it's the same. */
173 referenceSurface = SDLTest_ImagePrimitives();
174 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
175
176 /* Make current */
177 SDL_RenderPresent(renderer);
178
179 /* Clean up. */
180 SDL_DestroySurface(referenceSurface);
181 referenceSurface = NULL;
182
183 return TEST_COMPLETED;
184}
185
186/**
187 * Tests the SDL primitives for rendering within a viewport.
188 *
189 * \sa SDL_SetRenderDrawColor
190 * \sa SDL_RenderFillRect
191 * \sa SDL_RenderLine
192 *
193 */
194static int SDLCALL render_testPrimitivesWithViewport(void *arg)
195{
196 SDL_Rect viewport;
197 SDL_Surface *surface;
198
199 /* Clear surface. */
200 clearScreen();
201
202 viewport.x = 2;
203 viewport.y = 2;
204 viewport.w = 2;
205 viewport.h = 2;
206 CHECK_FUNC(SDL_SetRenderViewport, (renderer, &viewport));
207
208 CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 255, 255, 255, SDL_ALPHA_OPAQUE))
209 CHECK_FUNC(SDL_RenderLine, (renderer, 0.0f, 0.0f, 1.0f, 1.0f));
210
211 viewport.x = 3;
212 viewport.y = 3;
213 viewport.w = 1;
214 viewport.h = 1;
215 CHECK_FUNC(SDL_SetRenderViewport, (renderer, &viewport));
216
217 surface = SDL_RenderReadPixels(renderer, NULL);
218 if (surface) {
219 Uint8 r, g, b, a;
220 CHECK_FUNC(SDL_ReadSurfacePixel, (surface, 0, 0, &r, &g, &b, &a));
221 SDLTest_AssertCheck(r == 0xFF && g == 0xFF && b == 0xFF && a == 0xFF, "Validate diagonal line drawing with viewport, expected 0xFFFFFFFF, got 0x%.2x%.2x%.2x%.2x", r, g, b, a);
222 SDL_DestroySurface(surface);
223 } else {
224 SDLTest_AssertCheck(surface != NULL, "Validate result from SDL_RenderReadPixels, got NULL, %s", SDL_GetError());
225 }
226
227 return TEST_COMPLETED;
228}
229
230/**
231 * Tests some blitting routines.
232 *
233 * \sa SDL_RenderTexture
234 * \sa SDL_DestroyTexture
235 */
236static int SDLCALL render_testBlit(void *arg)
237{
238 int ret;
239 SDL_FRect rect;
240 SDL_Texture *tface;
241 SDL_Surface *referenceSurface = NULL;
242 int i, j, ni, nj;
243 int checkFailCount1;
244
245 /* Clear surface. */
246 clearScreen();
247
248 /* Need drawcolor or just skip test. */
249 SDLTest_AssertCheck(hasDrawColor(), "hasDrawColor)");
250
251 /* Create face surface. */
252 tface = loadTestFace();
253 SDLTest_AssertCheck(tface != NULL, "Verify loadTestFace() result");
254 if (tface == NULL) {
255 return TEST_ABORTED;
256 }
257
258 /* Constant values. */
259 rect.w = (float)tface->w;
260 rect.h = (float)tface->h;
261 ni = TESTRENDER_SCREEN_W - tface->w;
262 nj = TESTRENDER_SCREEN_H - tface->h;
263
264 /* Loop blit. */
265 checkFailCount1 = 0;
266 for (j = 0; j <= nj; j += 4) {
267 for (i = 0; i <= ni; i += 4) {
268 /* Blitting. */
269 rect.x = (float)i;
270 rect.y = (float)j;
271 ret = SDL_RenderTexture(renderer, tface, NULL, &rect);
272 if (!ret) {
273 checkFailCount1++;
274 }
275 }
276 }
277 SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_RenderTexture, expected: 0, got: %i", checkFailCount1);
278
279 /* See if it's the same */
280 referenceSurface = SDLTest_ImageBlit();
281 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
282
283 /* Make current */
284 SDL_RenderPresent(renderer);
285
286 /* Clean up. */
287 SDL_DestroyTexture(tface);
288 SDL_DestroySurface(referenceSurface);
289 referenceSurface = NULL;
290
291 return TEST_COMPLETED;
292}
293
294/**
295 * Tests tiled blitting routines.
296 */
297static int SDLCALL render_testBlitTiled(void *arg)
298{
299 int ret;
300 SDL_FRect rect;
301 SDL_Texture *tface;
302 SDL_Surface *referenceSurface = NULL;
303 SDL_Surface *referenceSurface2x = NULL;
304
305 /* Create face surface. */
306 tface = loadTestFace();
307 SDLTest_AssertCheck(tface != NULL, "Verify loadTestFace() result");
308 if (tface == NULL) {
309 return TEST_ABORTED;
310 }
311 SDL_SetTextureScaleMode(tface, SDL_SCALEMODE_NEAREST); /* So 2x scaling is pixel perfect */
312
313 /* Tiled blit - 1.0 scale */
314 {
315 /* Clear surface. */
316 clearScreen();
317
318 /* Tiled blit. */
319 rect.x = 0.0f;
320 rect.y = 0.0f;
321 rect.w = (float)TESTRENDER_SCREEN_W;
322 rect.h = (float)TESTRENDER_SCREEN_H;
323 ret = SDL_RenderTextureTiled(renderer, tface, NULL, 1.0f, &rect);
324 SDLTest_AssertCheck(ret == true, "Validate results from call to SDL_RenderTextureTiled, expected: true, got: %i", ret);
325
326 /* See if it's the same */
327 referenceSurface = SDLTest_ImageBlitTiled();
328 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
329
330 /* Make current */
331 SDL_RenderPresent(renderer);
332 }
333
334 /* Tiled blit - 2.0 scale */
335 {
336 /* Clear surface. */
337 clearScreen();
338
339 /* Tiled blit. */
340 rect.x = 0.0f;
341 rect.y = 0.0f;
342 rect.w = (float)TESTRENDER_SCREEN_W * 2;
343 rect.h = (float)TESTRENDER_SCREEN_H * 2;
344 ret = SDL_RenderTextureTiled(renderer, tface, NULL, 2.0f, &rect);
345 SDLTest_AssertCheck(ret == true, "Validate results from call to SDL_RenderTextureTiled, expected: true, got: %i", ret);
346
347 /* See if it's the same */
348 referenceSurface2x = SDL_CreateSurface(referenceSurface->w * 2, referenceSurface->h * 2, referenceSurface->format);
349 SDL_BlitSurfaceScaled(referenceSurface, NULL, referenceSurface2x, NULL, SDL_SCALEMODE_NEAREST);
350 SDLTest_AssertCheck(ret == true, "Validate results from call to SDL_BlitSurfaceScaled, expected: 0, got: %i", ret);
351 compare2x(referenceSurface2x, ALLOWABLE_ERROR_OPAQUE);
352
353 /* Make current */
354 SDL_RenderPresent(renderer);
355 }
356
357 /* Clean up. */
358 SDL_DestroyTexture(tface);
359 SDL_DestroySurface(referenceSurface);
360 SDL_DestroySurface(referenceSurface2x);
361 referenceSurface = NULL;
362
363 return TEST_COMPLETED;
364}
365
366static const Uint8 COLOR_SEPARATION = 85;
367
368static void Fill9GridReferenceSurface(SDL_Surface *surface, int left_width, int right_width, int top_height, int bottom_height)
369{
370 SDL_Rect rect;
371
372 // Upper left
373 rect.x = 0;
374 rect.y = 0;
375 rect.w = left_width;
376 rect.h = top_height;
377 SDL_FillSurfaceRect(surface, &rect, SDL_MapSurfaceRGB(surface, 1 * COLOR_SEPARATION, 1 * COLOR_SEPARATION, 0));
378
379 // Top
380 rect.x = left_width;
381 rect.y = 0;
382 rect.w = surface->w - left_width - right_width;
383 rect.h = top_height;
384 SDL_FillSurfaceRect(surface, &rect, SDL_MapSurfaceRGB(surface, 2 * COLOR_SEPARATION, 1 * COLOR_SEPARATION, 0));
385
386 // Upper right
387 rect.x = surface->w - right_width;
388 rect.y = 0;
389 rect.w = right_width;
390 rect.h = top_height;
391 SDL_FillSurfaceRect(surface, &rect, SDL_MapSurfaceRGB(surface, 3 * COLOR_SEPARATION, 1 * COLOR_SEPARATION, 0));
392
393 // Left
394 rect.x = 0;
395 rect.y = top_height;
396 rect.w = left_width;
397 rect.h = surface->h - top_height - bottom_height;
398 SDL_FillSurfaceRect(surface, &rect, SDL_MapSurfaceRGB(surface, 1 * COLOR_SEPARATION, 2 * COLOR_SEPARATION, 0));
399
400 // Center
401 rect.x = left_width;
402 rect.y = top_height;
403 rect.w = surface->w - right_width - left_width;
404 rect.h = surface->h - top_height - bottom_height;
405 SDL_FillSurfaceRect(surface, &rect, SDL_MapSurfaceRGB(surface, 2 * COLOR_SEPARATION, 2 * COLOR_SEPARATION, 0));
406
407 // Right
408 rect.x = surface->w - right_width;
409 rect.y = top_height;
410 rect.w = right_width;
411 rect.h = surface->h - top_height - bottom_height;
412 SDL_FillSurfaceRect(surface, &rect, SDL_MapSurfaceRGB(surface, 3 * COLOR_SEPARATION, 2 * COLOR_SEPARATION, 0));
413
414 // Lower left
415 rect.x = 0;
416 rect.y = surface->h - bottom_height;
417 rect.w = left_width;
418 rect.h = bottom_height;
419 SDL_FillSurfaceRect(surface, &rect, SDL_MapSurfaceRGB(surface, 1 * COLOR_SEPARATION, 3 * COLOR_SEPARATION, 0));
420
421 // Bottom
422 rect.x = left_width;
423 rect.y = surface->h - bottom_height;
424 rect.w = surface->w - left_width - right_width;
425 rect.h = bottom_height;
426 SDL_FillSurfaceRect(surface, &rect, SDL_MapSurfaceRGB(surface, 2 * COLOR_SEPARATION, 3 * COLOR_SEPARATION, 0));
427
428 // Lower right
429 rect.x = surface->w - right_width;
430 rect.y = surface->h - bottom_height;
431 rect.w = right_width;
432 rect.h = bottom_height;
433 SDL_FillSurfaceRect(surface, &rect, SDL_MapSurfaceRGB(surface, 3 * COLOR_SEPARATION, 3 * COLOR_SEPARATION, 0));
434}
435
436/**
437 * Tests 9-grid blitting.
438 */
439static int SDLCALL render_testBlit9Grid(void *arg)
440{
441 SDL_Surface *referenceSurface = NULL;
442 SDL_Surface *source = NULL;
443 SDL_Texture *texture;
444 int x, y;
445 SDL_FRect rect;
446 int ret = 0;
447
448 /* Create source surface */
449 source = SDL_CreateSurface(3, 3, SDL_PIXELFORMAT_RGBA32);
450 SDLTest_AssertCheck(source != NULL, "Verify source surface is not NULL");
451 for (y = 0; y < 3; ++y) {
452 for (x = 0; x < 3; ++x) {
453 SDL_WriteSurfacePixel(source, x, y, (Uint8)((1 + x) * COLOR_SEPARATION), (Uint8)((1 + y) * COLOR_SEPARATION), 0, 255);
454 }
455 }
456 texture = SDL_CreateTextureFromSurface(renderer, source);
457 SDLTest_AssertCheck(texture != NULL, "Verify source texture is not NULL");
458 ret = SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST);
459 SDLTest_AssertCheck(ret == true, "Validate results from call to SDL_SetTextureScaleMode, expected: true, got: %i", ret);
460
461 /* 9-grid blit - 1.0 scale */
462 {
463 SDLTest_Log("9-grid blit - 1.0 scale");
464 /* Create reference surface */
465 SDL_DestroySurface(referenceSurface);
466 referenceSurface = SDL_CreateSurface(TESTRENDER_SCREEN_W, TESTRENDER_SCREEN_H, SDL_PIXELFORMAT_RGBA32);
467 SDLTest_AssertCheck(referenceSurface != NULL, "Verify reference surface is not NULL");
468 Fill9GridReferenceSurface(referenceSurface, 1, 1, 1, 1);
469
470 /* Clear surface. */
471 clearScreen();
472
473 /* Tiled blit. */
474 rect.x = 0.0f;
475 rect.y = 0.0f;
476 rect.w = (float)TESTRENDER_SCREEN_W;
477 rect.h = (float)TESTRENDER_SCREEN_H;
478 ret = SDL_RenderTexture9Grid(renderer, texture, NULL, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, &rect);
479 SDLTest_AssertCheck(ret == true, "Validate results from call to SDL_RenderTexture9Grid, expected: true, got: %i", ret);
480
481 /* See if it's the same */
482 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
483
484 /* Make current */
485 SDL_RenderPresent(renderer);
486 }
487
488 /* 9-grid blit - 2.0 scale */
489 {
490 SDLTest_Log("9-grid blit - 2.0 scale");
491 /* Create reference surface */
492 SDL_DestroySurface(referenceSurface);
493 referenceSurface = SDL_CreateSurface(TESTRENDER_SCREEN_W, TESTRENDER_SCREEN_H, SDL_PIXELFORMAT_RGBA32);
494 SDLTest_AssertCheck(referenceSurface != NULL, "Verify reference surface is not NULL");
495 Fill9GridReferenceSurface(referenceSurface, 2, 2, 2, 2);
496
497 /* Clear surface. */
498 clearScreen();
499
500 /* Tiled blit. */
501 rect.x = 0.0f;
502 rect.y = 0.0f;
503 rect.w = (float)TESTRENDER_SCREEN_W;
504 rect.h = (float)TESTRENDER_SCREEN_H;
505 ret = SDL_RenderTexture9Grid(renderer, texture, NULL, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, &rect);
506 SDLTest_AssertCheck(ret == true, "Validate results from call to SDL_RenderTexture9Grid, expected: true, got: %i", ret);
507
508 /* See if it's the same */
509 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
510
511 /* Make current */
512 SDL_RenderPresent(renderer);
513 }
514
515 /* Clean up. */
516 SDL_DestroySurface(source);
517 SDL_DestroyTexture(texture);
518
519 /* Create complex source surface */
520 source = SDL_CreateSurface(5, 5, SDL_PIXELFORMAT_RGBA32);
521 SDLTest_AssertCheck(source != NULL, "Verify source surface is not NULL");
522 SDL_WriteSurfacePixel(source, 0, 0, (Uint8)((1) * COLOR_SEPARATION), (Uint8)((1) * COLOR_SEPARATION), 0, 255);
523 SDL_WriteSurfacePixel(source, 1, 0, (Uint8)((2) * COLOR_SEPARATION), (Uint8)((1) * COLOR_SEPARATION), 0, 255);
524 SDL_WriteSurfacePixel(source, 2, 0, (Uint8)((2) * COLOR_SEPARATION), (Uint8)((1) * COLOR_SEPARATION), 0, 255);
525 SDL_WriteSurfacePixel(source, 3, 0, (Uint8)((3) * COLOR_SEPARATION), (Uint8)((1) * COLOR_SEPARATION), 0, 255);
526 SDL_WriteSurfacePixel(source, 4, 0, (Uint8)((3) * COLOR_SEPARATION), (Uint8)((1) * COLOR_SEPARATION), 0, 255);
527
528 SDL_WriteSurfacePixel(source, 0, 1, (Uint8)((1) * COLOR_SEPARATION), (Uint8)((2) * COLOR_SEPARATION), 0, 255);
529 SDL_WriteSurfacePixel(source, 1, 1, (Uint8)((2) * COLOR_SEPARATION), (Uint8)((2) * COLOR_SEPARATION), 0, 255);
530 SDL_WriteSurfacePixel(source, 2, 1, (Uint8)((2) * COLOR_SEPARATION), (Uint8)((2) * COLOR_SEPARATION), 0, 255);
531 SDL_WriteSurfacePixel(source, 3, 1, (Uint8)((3) * COLOR_SEPARATION), (Uint8)((2) * COLOR_SEPARATION), 0, 255);
532 SDL_WriteSurfacePixel(source, 4, 1, (Uint8)((3) * COLOR_SEPARATION), (Uint8)((2) * COLOR_SEPARATION), 0, 255);
533
534 SDL_WriteSurfacePixel(source, 0, 2, (Uint8)((1) * COLOR_SEPARATION), (Uint8)((2) * COLOR_SEPARATION), 0, 255);
535 SDL_WriteSurfacePixel(source, 1, 2, (Uint8)((2) * COLOR_SEPARATION), (Uint8)((2) * COLOR_SEPARATION), 0, 255);
536 SDL_WriteSurfacePixel(source, 2, 2, (Uint8)((2) * COLOR_SEPARATION), (Uint8)((2) * COLOR_SEPARATION), 0, 255);
537 SDL_WriteSurfacePixel(source, 3, 2, (Uint8)((3) * COLOR_SEPARATION), (Uint8)((2) * COLOR_SEPARATION), 0, 255);
538 SDL_WriteSurfacePixel(source, 4, 2, (Uint8)((3) * COLOR_SEPARATION), (Uint8)((2) * COLOR_SEPARATION), 0, 255);
539
540 SDL_WriteSurfacePixel(source, 0, 3, (Uint8)((1) * COLOR_SEPARATION), (Uint8)((3) * COLOR_SEPARATION), 0, 255);
541 SDL_WriteSurfacePixel(source, 1, 3, (Uint8)((2) * COLOR_SEPARATION), (Uint8)((3) * COLOR_SEPARATION), 0, 255);
542 SDL_WriteSurfacePixel(source, 2, 3, (Uint8)((2) * COLOR_SEPARATION), (Uint8)((3) * COLOR_SEPARATION), 0, 255);
543 SDL_WriteSurfacePixel(source, 3, 3, (Uint8)((3) * COLOR_SEPARATION), (Uint8)((3) * COLOR_SEPARATION), 0, 255);
544 SDL_WriteSurfacePixel(source, 4, 3, (Uint8)((3) * COLOR_SEPARATION), (Uint8)((3) * COLOR_SEPARATION), 0, 255);
545
546 SDL_WriteSurfacePixel(source, 0, 4, (Uint8)((1) * COLOR_SEPARATION), (Uint8)((3) * COLOR_SEPARATION), 0, 255);
547 SDL_WriteSurfacePixel(source, 1, 4, (Uint8)((2) * COLOR_SEPARATION), (Uint8)((3) * COLOR_SEPARATION), 0, 255);
548 SDL_WriteSurfacePixel(source, 2, 4, (Uint8)((2) * COLOR_SEPARATION), (Uint8)((3) * COLOR_SEPARATION), 0, 255);
549 SDL_WriteSurfacePixel(source, 3, 4, (Uint8)((3) * COLOR_SEPARATION), (Uint8)((3) * COLOR_SEPARATION), 0, 255);
550 SDL_WriteSurfacePixel(source, 4, 4, (Uint8)((3) * COLOR_SEPARATION), (Uint8)((3) * COLOR_SEPARATION), 0, 255);
551
552 texture = SDL_CreateTextureFromSurface(renderer, source);
553 SDLTest_AssertCheck(texture != NULL, "Verify source texture is not NULL");
554 ret = SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST);
555 SDLTest_AssertCheck(ret == true, "Validate results from call to SDL_SetTextureScaleMode, expected: true, got: %i", ret);
556
557 /* complex 9-grid blit - 1.0 scale */
558 {
559 SDLTest_Log("complex 9-grid blit - 1.0 scale");
560 /* Create reference surface */
561 SDL_DestroySurface(referenceSurface);
562 referenceSurface = SDL_CreateSurface(TESTRENDER_SCREEN_W, TESTRENDER_SCREEN_H, SDL_PIXELFORMAT_RGBA32);
563 SDLTest_AssertCheck(referenceSurface != NULL, "Verify reference surface is not NULL");
564 Fill9GridReferenceSurface(referenceSurface, 1, 2, 1, 2);
565
566 /* Clear surface. */
567 clearScreen();
568
569 /* Tiled blit. */
570 rect.x = 0.0f;
571 rect.y = 0.0f;
572 rect.w = (float)TESTRENDER_SCREEN_W;
573 rect.h = (float)TESTRENDER_SCREEN_H;
574 ret = SDL_RenderTexture9Grid(renderer, texture, NULL, 1.0f, 2.0f, 1.0f, 2.0f, 1.0f, &rect);
575 SDLTest_AssertCheck(ret == true, "Validate results from call to SDL_RenderTexture9Grid, expected: true, got: %i", ret);
576
577 /* See if it's the same */
578 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
579
580 /* Make current */
581 SDL_RenderPresent(renderer);
582 }
583
584 /* complex 9-grid blit - 2.0 scale */
585 {
586 SDLTest_Log("complex 9-grid blit - 2.0 scale");
587 /* Create reference surface */
588 SDL_DestroySurface(referenceSurface);
589 referenceSurface = SDL_CreateSurface(TESTRENDER_SCREEN_W, TESTRENDER_SCREEN_H, SDL_PIXELFORMAT_RGBA32);
590 SDLTest_AssertCheck(referenceSurface != NULL, "Verify reference surface is not NULL");
591 Fill9GridReferenceSurface(referenceSurface, 2, 4, 2, 4);
592
593 /* Clear surface. */
594 clearScreen();
595
596 /* Tiled blit. */
597 rect.x = 0.0f;
598 rect.y = 0.0f;
599 rect.w = (float)TESTRENDER_SCREEN_W;
600 rect.h = (float)TESTRENDER_SCREEN_H;
601 ret = SDL_RenderTexture9Grid(renderer, texture, NULL, 1.0f, 2.0f, 1.0f, 2.0f, 2.0f, &rect);
602 SDLTest_AssertCheck(ret == true, "Validate results from call to SDL_RenderTexture9Grid, expected: true, got: %i", ret);
603
604 /* See if it's the same */
605 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
606
607 /* Make current */
608 SDL_RenderPresent(renderer);
609 }
610
611 /* Clean up. */
612 SDL_DestroySurface(referenceSurface);
613 SDL_DestroySurface(source);
614 SDL_DestroyTexture(texture);
615
616 return TEST_COMPLETED;
617}
618
619/**
620 * Blits doing color tests.
621 *
622 * \sa SDL_SetTextureColorMod
623 * \sa SDL_RenderTexture
624 * \sa SDL_DestroyTexture
625 */
626static int SDLCALL render_testBlitColor(void *arg)
627{
628 int ret;
629 SDL_FRect rect;
630 SDL_Texture *tface;
631 SDL_Surface *referenceSurface = NULL;
632 int i, j, ni, nj;
633 int checkFailCount1;
634 int checkFailCount2;
635
636 /* Clear surface. */
637 clearScreen();
638
639 /* Create face surface. */
640 tface = loadTestFace();
641 SDLTest_AssertCheck(tface != NULL, "Verify loadTestFace() result");
642 if (tface == NULL) {
643 return TEST_ABORTED;
644 }
645
646 /* Constant values. */
647 rect.w = (float)tface->w;
648 rect.h = (float)tface->h;
649 ni = TESTRENDER_SCREEN_W - tface->w;
650 nj = TESTRENDER_SCREEN_H - tface->h;
651
652 /* Test blitting with color mod. */
653 checkFailCount1 = 0;
654 checkFailCount2 = 0;
655 for (j = 0; j <= nj; j += 4) {
656 for (i = 0; i <= ni; i += 4) {
657 /* Set color mod. */
658 ret = SDL_SetTextureColorMod(tface, (Uint8)((255 / nj) * j), (Uint8)((255 / ni) * i), (Uint8)((255 / nj) * j));
659 if (!ret) {
660 checkFailCount1++;
661 }
662
663 /* Blitting. */
664 rect.x = (float)i;
665 rect.y = (float)j;
666 ret = SDL_RenderTexture(renderer, tface, NULL, &rect);
667 if (!ret) {
668 checkFailCount2++;
669 }
670 }
671 }
672 SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetTextureColorMod, expected: 0, got: %i", checkFailCount1);
673 SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_RenderTexture, expected: 0, got: %i", checkFailCount2);
674
675 /* See if it's the same. */
676 referenceSurface = SDLTest_ImageBlitColor();
677 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
678
679 /* Make current */
680 SDL_RenderPresent(renderer);
681
682 /* Clean up. */
683 SDL_DestroyTexture(tface);
684 SDL_DestroySurface(referenceSurface);
685 referenceSurface = NULL;
686
687 return TEST_COMPLETED;
688}
689
690typedef enum TestRenderOperation
691{
692 TEST_RENDER_POINT,
693 TEST_RENDER_LINE,
694 TEST_RENDER_RECT,
695 TEST_RENDER_COPY_XRGB,
696 TEST_RENDER_COPY_ARGB,
697} TestRenderOperation;
698
699/**
700 * Helper that tests a specific operation and blend mode, -1 for color mod, -2 for alpha mod
701 */
702static void testBlendModeOperation(TestRenderOperation op, int mode, SDL_PixelFormat dst_format)
703{
704 /* Allow up to 2 delta from theoretical value to account for rounding error.
705 * We allow 2 rounding errors because the software renderer breaks drawing operations into alpha multiplication and a separate blend operation.
706 */
707 const int MAXIMUM_ERROR = 2;
708 int ret;
709 SDL_Texture *src = NULL;
710 SDL_Texture *dst;
711 SDL_Surface *result;
712 Uint8 srcR = 10, srcG = 128, srcB = 240, srcA = 100;
713 Uint8 dstR = 128, dstG = 128, dstB = 128, dstA = 128;
714 Uint8 expectedR, expectedG, expectedB, expectedA;
715 Uint8 actualR, actualG, actualB, actualA;
716 int deltaR, deltaG, deltaB, deltaA;
717 const char *operation = "UNKNOWN";
718 const char *mode_name = "UNKNOWN";
719
720 /* Create dst surface */
721 dst = SDL_CreateTexture(renderer, dst_format, SDL_TEXTUREACCESS_TARGET, 3, 3);
722 SDLTest_AssertCheck(dst != NULL, "Verify dst surface is not NULL");
723 if (dst == NULL) {
724 return;
725 }
726 if (SDL_ISPIXELFORMAT_ALPHA(dst_format)) {
727 SDL_BlendMode blendMode = SDL_BLENDMODE_NONE;
728 ret = SDL_GetTextureBlendMode(dst, &blendMode);
729 SDLTest_AssertCheck(ret == true, "Verify result from SDL_GetTextureBlendMode(), expected: true, got: %i", ret);
730 SDLTest_AssertCheck(blendMode == SDL_BLENDMODE_BLEND, "Verify alpha texture blend mode, expected %d, got %" SDL_PRIu32, SDL_BLENDMODE_BLEND, blendMode);
731 }
732
733 /* Set as render target */
734 SDL_SetRenderTarget(renderer, dst);
735
736 /* Clear surface. */
737 if (!SDL_ISPIXELFORMAT_ALPHA(dst_format)) {
738 dstA = 255;
739 }
740 ret = SDL_SetRenderDrawColor(renderer, dstR, dstG, dstB, dstA);
741 SDLTest_AssertCheck(ret == true, "Verify result from SDL_SetRenderDrawColor(), expected: true, got: %i", ret);
742 ret = SDL_RenderClear(renderer);
743 SDLTest_AssertPass("Call to SDL_RenderClear()");
744 SDLTest_AssertCheck(ret == true, "Verify result from SDL_RenderClear, expected: true, got: %i", ret);
745
746 if (op == TEST_RENDER_COPY_XRGB || op == TEST_RENDER_COPY_ARGB) {
747 Uint8 pixels[4];
748
749 /* Create src surface */
750 src = SDL_CreateTexture(renderer, op == TEST_RENDER_COPY_XRGB ? SDL_PIXELFORMAT_RGBX32 : SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, 1, 1);
751 SDLTest_AssertCheck(src != NULL, "Verify src surface is not NULL");
752 if (src == NULL) {
753 return;
754 }
755
756 /* Clear surface. */
757 if (op == TEST_RENDER_COPY_XRGB) {
758 srcA = 255;
759 }
760 pixels[0] = srcR;
761 pixels[1] = srcG;
762 pixels[2] = srcB;
763 pixels[3] = srcA;
764 SDL_UpdateTexture(src, NULL, pixels, sizeof(pixels));
765
766 /* Set blend mode. */
767 if (mode >= 0) {
768 ret = SDL_SetTextureBlendMode(src, (SDL_BlendMode)mode);
769 SDLTest_AssertPass("Call to SDL_SetTextureBlendMode()");
770 SDLTest_AssertCheck(ret == true, "Verify result from SDL_SetTextureBlendMode(..., %i), expected: true, got: %i", mode, ret);
771 } else {
772 ret = SDL_SetTextureBlendMode(src, SDL_BLENDMODE_BLEND);
773 SDLTest_AssertPass("Call to SDL_SetTextureBlendMode()");
774 SDLTest_AssertCheck(ret == true, "Verify result from SDL_SetTextureBlendMode(..., %i), expected: true, got: %i", mode, ret);
775 }
776 } else {
777 /* Set draw color */
778 ret = SDL_SetRenderDrawColor(renderer, srcR, srcG, srcB, srcA);
779 SDLTest_AssertCheck(ret == true, "Verify result from SDL_SetRenderDrawColor(), expected: true, got: %i", ret);
780
781 /* Set blend mode. */
782 if (mode >= 0) {
783 ret = SDL_SetRenderDrawBlendMode(renderer, (SDL_BlendMode)mode);
784 SDLTest_AssertPass("Call to SDL_SetRenderDrawBlendMode()");
785 SDLTest_AssertCheck(ret == true, "Verify result from SDL_SetRenderDrawBlendMode(..., %i), expected: true, got: %i", mode, ret);
786 } else {
787 ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
788 SDLTest_AssertPass("Call to SDL_SetRenderDrawBlendMode()");
789 SDLTest_AssertCheck(ret == true, "Verify result from SDL_SetRenderDrawBlendMode(..., %i), expected: true, got: %i", mode, ret);
790 }
791 }
792
793 /* Test blend mode. */
794#define FLOAT(X) ((float)X / 255.0f)
795 switch (mode) {
796 case -1:
797 mode_name = "color modulation";
798 ret = SDL_SetTextureColorMod(src, srcR, srcG, srcB);
799 SDLTest_AssertCheck(ret == true, "Validate results from calls to SDL_SetTextureColorMod, expected: true, got: %i", ret);
800 expectedR = (Uint8)SDL_roundf(SDL_clamp((FLOAT(srcR) * FLOAT(srcR)) * FLOAT(srcA) + FLOAT(dstR) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
801 expectedG = (Uint8)SDL_roundf(SDL_clamp((FLOAT(srcG) * FLOAT(srcG)) * FLOAT(srcA) + FLOAT(dstG) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
802 expectedB = (Uint8)SDL_roundf(SDL_clamp((FLOAT(srcB) * FLOAT(srcB)) * FLOAT(srcA) + FLOAT(dstB) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
803 expectedA = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcA) + FLOAT(dstA) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
804 break;
805 case -2:
806 mode_name = "alpha modulation";
807 ret = SDL_SetTextureAlphaMod(src, srcA);
808 SDLTest_AssertCheck(ret == true, "Validate results from calls to SDL_SetTextureAlphaMod, expected: true, got: %i", ret);
809 expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * (FLOAT(srcA) * FLOAT(srcA)) + FLOAT(dstR) * (1.0f - (FLOAT(srcA) * FLOAT(srcA))), 0.0f, 1.0f) * 255.0f);
810 expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * (FLOAT(srcA) * FLOAT(srcA)) + FLOAT(dstG) * (1.0f - (FLOAT(srcA) * FLOAT(srcA))), 0.0f, 1.0f) * 255.0f);
811 expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * (FLOAT(srcA) * FLOAT(srcA)) + FLOAT(dstB) * (1.0f - (FLOAT(srcA) * FLOAT(srcA))), 0.0f, 1.0f) * 255.0f);
812 expectedA = (Uint8)SDL_roundf(SDL_clamp((FLOAT(srcA) * FLOAT(srcA)) + FLOAT(dstA) * (1.0f - (FLOAT(srcA) * FLOAT(srcA))), 0.0f, 1.0f) * 255.0f);
813 break;
814 case SDL_BLENDMODE_NONE:
815 mode_name = "SDL_BLENDMODE_NONE";
816 expectedR = srcR;
817 expectedG = srcG;
818 expectedB = srcB;
819 expectedA = SDL_ISPIXELFORMAT_ALPHA(dst_format) ? srcA : 255;
820 break;
821 case SDL_BLENDMODE_BLEND:
822 mode_name = "SDL_BLENDMODE_BLEND";
823 expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * FLOAT(srcA) + FLOAT(dstR) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
824 expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * FLOAT(srcA) + FLOAT(dstG) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
825 expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * FLOAT(srcA) + FLOAT(dstB) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
826 expectedA = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcA) + FLOAT(dstA) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
827 break;
828 case SDL_BLENDMODE_BLEND_PREMULTIPLIED:
829 mode_name = "SDL_BLENDMODE_BLEND_PREMULTIPLIED";
830 expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) + FLOAT(dstR) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
831 expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) + FLOAT(dstG) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
832 expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) + FLOAT(dstB) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
833 expectedA = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcA) + FLOAT(dstA) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
834 break;
835 case SDL_BLENDMODE_ADD:
836 mode_name = "SDL_BLENDMODE_ADD";
837 expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * FLOAT(srcA) + FLOAT(dstR), 0.0f, 1.0f) * 255.0f);
838 expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * FLOAT(srcA) + FLOAT(dstG), 0.0f, 1.0f) * 255.0f);
839 expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * FLOAT(srcA) + FLOAT(dstB), 0.0f, 1.0f) * 255.0f);
840 expectedA = dstA;
841 break;
842 case SDL_BLENDMODE_ADD_PREMULTIPLIED:
843 mode_name = "SDL_BLENDMODE_ADD_PREMULTIPLIED";
844 expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) + FLOAT(dstR), 0.0f, 1.0f) * 255.0f);
845 expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) + FLOAT(dstG), 0.0f, 1.0f) * 255.0f);
846 expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) + FLOAT(dstB), 0.0f, 1.0f) * 255.0f);
847 expectedA = dstA;
848 break;
849 case SDL_BLENDMODE_MOD:
850 mode_name = "SDL_BLENDMODE_MOD";
851 expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * FLOAT(dstR), 0.0f, 1.0f) * 255.0f);
852 expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * FLOAT(dstG), 0.0f, 1.0f) * 255.0f);
853 expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * FLOAT(dstB), 0.0f, 1.0f) * 255.0f);
854 expectedA = dstA;
855 break;
856 case SDL_BLENDMODE_MUL:
857 mode_name = "SDL_BLENDMODE_MUL";
858 expectedR = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcR) * FLOAT(dstR) + FLOAT(dstR) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
859 expectedG = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcG) * FLOAT(dstG) + FLOAT(dstG) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
860 expectedB = (Uint8)SDL_roundf(SDL_clamp(FLOAT(srcB) * FLOAT(dstB) + FLOAT(dstB) * (1.0f - FLOAT(srcA)), 0.0f, 1.0f) * 255.0f);
861 expectedA = dstA;
862 break;
863 default:
864 SDLTest_LogError("Invalid blending mode: %d", mode);
865 return;
866 }
867
868 switch (op) {
869 case TEST_RENDER_POINT:
870 operation = "render point";
871 ret = SDL_RenderPoint(renderer, 0.0f, 0.0f);
872 SDLTest_AssertCheck(ret == true, "Validate results from calls to SDL_RenderPoint, expected: 0, got: %i", ret);
873 break;
874 case TEST_RENDER_LINE:
875 operation = "render line";
876 ret = SDL_RenderLine(renderer, 0.0f, 0.0f, 2.0f, 2.0f);
877 SDLTest_AssertCheck(ret == true, "Validate results from calls to SDL_RenderLine, expected: true, got: %i", ret);
878 break;
879 case TEST_RENDER_RECT:
880 operation = "render rect";
881 ret = SDL_RenderFillRect(renderer, NULL);
882 SDLTest_AssertCheck(ret == true, "Validate results from calls to SDL_RenderFillRect, expected: 0, got: %i", ret);
883 break;
884 case TEST_RENDER_COPY_XRGB:
885 case TEST_RENDER_COPY_ARGB:
886 operation = (op == TEST_RENDER_COPY_XRGB) ? "render XRGB" : "render ARGB";
887 ret = SDL_RenderTexture(renderer, src, NULL, NULL);
888 SDLTest_AssertCheck(ret == true, "Validate results from calls to SDL_RenderTexture, expected: true, got: %i", ret);
889 break;
890 default:
891 SDLTest_LogError("Invalid blending operation: %d", op);
892 return;
893 }
894
895 result = SDL_RenderReadPixels(renderer, NULL);
896 SDL_ReadSurfacePixel(result, 0, 0, &actualR, &actualG, &actualB, &actualA);
897 deltaR = SDL_abs((int)actualR - expectedR);
898 deltaG = SDL_abs((int)actualG - expectedG);
899 deltaB = SDL_abs((int)actualB - expectedB);
900 deltaA = SDL_abs((int)actualA - expectedA);
901 SDLTest_AssertCheck(
902 deltaR <= MAXIMUM_ERROR &&
903 deltaG <= MAXIMUM_ERROR &&
904 deltaB <= MAXIMUM_ERROR &&
905 deltaA <= MAXIMUM_ERROR,
906 "Checking %s %s operation results, expected %d,%d,%d,%d, got %d,%d,%d,%d",
907 operation, mode_name,
908 expectedR, expectedG, expectedB, expectedA, actualR, actualG, actualB, actualA);
909
910 /* Clean up */
911 SDL_DestroySurface(result);
912 SDL_DestroyTexture(src);
913 SDL_DestroyTexture(dst);
914}
915
916static void testBlendMode(int mode)
917{
918 const TestRenderOperation operations[] = {
919 TEST_RENDER_POINT,
920 TEST_RENDER_LINE,
921 TEST_RENDER_RECT,
922 TEST_RENDER_COPY_XRGB,
923 TEST_RENDER_COPY_ARGB
924 };
925 const SDL_PixelFormat dst_formats[] = {
926 SDL_PIXELFORMAT_XRGB8888, SDL_PIXELFORMAT_ARGB8888
927 };
928 int i, j;
929
930 for (i = 0; i < SDL_arraysize(operations); ++i) {
931 for (j = 0; j < SDL_arraysize(dst_formats); ++j) {
932 TestRenderOperation op = operations[i];
933
934 if (mode < 0) {
935 if (op != TEST_RENDER_COPY_XRGB && op != TEST_RENDER_COPY_ARGB) {
936 /* Unsupported mode for this operation */
937 continue;
938 }
939 }
940 testBlendModeOperation(op, mode, dst_formats[j]);
941 }
942 }
943}
944
945/**
946 * Tests render operations with blend modes
947 */
948static int SDLCALL render_testBlendModes(void *arg)
949{
950 testBlendMode(-1);
951 testBlendMode(-2);
952 testBlendMode(SDL_BLENDMODE_NONE);
953 testBlendMode(SDL_BLENDMODE_BLEND);
954 testBlendMode(SDL_BLENDMODE_BLEND_PREMULTIPLIED);
955 testBlendMode(SDL_BLENDMODE_ADD);
956 testBlendMode(SDL_BLENDMODE_ADD_PREMULTIPLIED);
957 testBlendMode(SDL_BLENDMODE_MOD);
958 testBlendMode(SDL_BLENDMODE_MUL);
959
960 return TEST_COMPLETED;
961}
962
963/**
964 * Test viewport
965 */
966static int SDLCALL render_testViewport(void *arg)
967{
968 SDL_Surface *referenceSurface;
969 SDL_Rect viewport;
970
971 viewport.x = TESTRENDER_SCREEN_W / 3;
972 viewport.y = TESTRENDER_SCREEN_H / 3;
973 viewport.w = TESTRENDER_SCREEN_W / 2;
974 viewport.h = TESTRENDER_SCREEN_H / 2;
975
976 /* Create expected result */
977 referenceSurface = SDL_CreateSurface(TESTRENDER_SCREEN_W, TESTRENDER_SCREEN_H, RENDER_COMPARE_FORMAT);
978 CHECK_FUNC(SDL_FillSurfaceRect, (referenceSurface, NULL, RENDER_COLOR_CLEAR))
979 CHECK_FUNC(SDL_FillSurfaceRect, (referenceSurface, &viewport, RENDER_COLOR_GREEN))
980
981 /* Clear surface. */
982 clearScreen();
983
984 /* Set the viewport and do a fill operation */
985 CHECK_FUNC(SDL_SetRenderViewport, (renderer, &viewport))
986 CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 0, 255, 0, SDL_ALPHA_OPAQUE))
987 CHECK_FUNC(SDL_RenderFillRect, (renderer, NULL))
988 CHECK_FUNC(SDL_SetRenderViewport, (renderer, NULL))
989
990 /* Check to see if final image matches. */
991 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
992
993 /*
994 * Verify that clear ignores the viewport
995 */
996
997 /* Create expected result */
998 CHECK_FUNC(SDL_FillSurfaceRect, (referenceSurface, NULL, RENDER_COLOR_GREEN))
999
1000 /* Clear surface. */
1001 clearScreen();
1002
1003 /* Set the viewport and do a clear operation */
1004 CHECK_FUNC(SDL_SetRenderViewport, (renderer, &viewport))
1005 CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 0, 255, 0, SDL_ALPHA_OPAQUE))
1006 CHECK_FUNC(SDL_RenderClear, (renderer))
1007 CHECK_FUNC(SDL_SetRenderViewport, (renderer, NULL))
1008
1009 /* Check to see if final image matches. */
1010 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
1011
1012 /* Make current */
1013 SDL_RenderPresent(renderer);
1014
1015 SDL_DestroySurface(referenceSurface);
1016
1017 return TEST_COMPLETED;
1018}
1019
1020/**
1021 * Test clip rect
1022 */
1023static int SDLCALL render_testClipRect(void *arg)
1024{
1025 SDL_Surface *referenceSurface;
1026 SDL_Rect cliprect;
1027
1028 cliprect.x = TESTRENDER_SCREEN_W / 3;
1029 cliprect.y = TESTRENDER_SCREEN_H / 3;
1030 cliprect.w = TESTRENDER_SCREEN_W / 2;
1031 cliprect.h = TESTRENDER_SCREEN_H / 2;
1032
1033 /* Create expected result */
1034 referenceSurface = SDL_CreateSurface(TESTRENDER_SCREEN_W, TESTRENDER_SCREEN_H, RENDER_COMPARE_FORMAT);
1035 CHECK_FUNC(SDL_FillSurfaceRect, (referenceSurface, NULL, RENDER_COLOR_CLEAR))
1036 CHECK_FUNC(SDL_FillSurfaceRect, (referenceSurface, &cliprect, RENDER_COLOR_GREEN))
1037
1038 /* Clear surface. */
1039 clearScreen();
1040
1041 /* Set the cliprect and do a fill operation */
1042 CHECK_FUNC(SDL_SetRenderClipRect, (renderer, &cliprect))
1043 CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 0, 255, 0, SDL_ALPHA_OPAQUE))
1044 CHECK_FUNC(SDL_RenderFillRect, (renderer, NULL))
1045 CHECK_FUNC(SDL_SetRenderClipRect, (renderer, NULL))
1046
1047 /* Check to see if final image matches. */
1048 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
1049
1050 /*
1051 * Verify that clear ignores the cliprect
1052 */
1053
1054 /* Create expected result */
1055 CHECK_FUNC(SDL_FillSurfaceRect, (referenceSurface, NULL, RENDER_COLOR_GREEN))
1056
1057 /* Clear surface. */
1058 clearScreen();
1059
1060 /* Set the cliprect and do a clear operation */
1061 CHECK_FUNC(SDL_SetRenderClipRect, (renderer, &cliprect))
1062 CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 0, 255, 0, SDL_ALPHA_OPAQUE))
1063 CHECK_FUNC(SDL_RenderClear, (renderer))
1064 CHECK_FUNC(SDL_SetRenderClipRect, (renderer, NULL))
1065
1066 /* Check to see if final image matches. */
1067 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
1068
1069 /* Make current */
1070 SDL_RenderPresent(renderer);
1071
1072 SDL_DestroySurface(referenceSurface);
1073
1074 return TEST_COMPLETED;
1075}
1076
1077/**
1078 * Test logical size
1079 */
1080static int SDLCALL render_testLogicalSize(void *arg)
1081{
1082 SDL_Surface *referenceSurface;
1083 SDL_Rect viewport;
1084 SDL_FRect rect;
1085 int w, h;
1086 int set_w, set_h;
1087 SDL_RendererLogicalPresentation set_presentation_mode;
1088 SDL_FRect set_rect;
1089 const int factor = 2;
1090
1091 viewport.x = ((TESTRENDER_SCREEN_W / 4) / factor) * factor;
1092 viewport.y = ((TESTRENDER_SCREEN_H / 4) / factor) * factor;
1093 viewport.w = ((TESTRENDER_SCREEN_W / 2) / factor) * factor;
1094 viewport.h = ((TESTRENDER_SCREEN_H / 2) / factor) * factor;
1095
1096 /* Create expected result */
1097 referenceSurface = SDL_CreateSurface(TESTRENDER_SCREEN_W, TESTRENDER_SCREEN_H, RENDER_COMPARE_FORMAT);
1098 CHECK_FUNC(SDL_FillSurfaceRect, (referenceSurface, NULL, RENDER_COLOR_CLEAR))
1099 CHECK_FUNC(SDL_FillSurfaceRect, (referenceSurface, &viewport, RENDER_COLOR_GREEN))
1100
1101 /* Clear surface. */
1102 clearScreen();
1103
1104 /* Set the logical size and do a fill operation */
1105 CHECK_FUNC(SDL_GetCurrentRenderOutputSize, (renderer, &w, &h))
1106 CHECK_FUNC(SDL_SetRenderLogicalPresentation, (renderer, w / factor, h / factor, SDL_LOGICAL_PRESENTATION_LETTERBOX))
1107 CHECK_FUNC(SDL_GetRenderLogicalPresentation, (renderer, &set_w, &set_h, &set_presentation_mode))
1108 SDLTest_AssertCheck(
1109 set_w == (w / factor) &&
1110 set_h == (h / factor) &&
1111 set_presentation_mode == SDL_LOGICAL_PRESENTATION_LETTERBOX,
1112 "Validate result from SDL_GetRenderLogicalPresentation, got %d, %d, %d", set_w, set_h, set_presentation_mode);
1113 CHECK_FUNC(SDL_GetRenderLogicalPresentationRect, (renderer, &set_rect))
1114 SDLTest_AssertCheck(
1115 set_rect.x == 0.0f &&
1116 set_rect.y == 0.0f &&
1117 set_rect.w == 320.0f &&
1118 set_rect.h == 240.0f,
1119 "Validate result from SDL_GetRenderLogicalPresentationRect, got {%g, %g, %gx%g}", set_rect.x, set_rect.y, set_rect.w, set_rect.h);
1120 CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 0, 255, 0, SDL_ALPHA_OPAQUE))
1121 rect.x = (float)viewport.x / factor;
1122 rect.y = (float)viewport.y / factor;
1123 rect.w = (float)viewport.w / factor;
1124 rect.h = (float)viewport.h / factor;
1125 CHECK_FUNC(SDL_RenderFillRect, (renderer, &rect))
1126 CHECK_FUNC(SDL_SetRenderLogicalPresentation, (renderer, 0, 0, SDL_LOGICAL_PRESENTATION_DISABLED))
1127 CHECK_FUNC(SDL_GetRenderLogicalPresentation, (renderer, &set_w, &set_h, &set_presentation_mode))
1128 SDLTest_AssertCheck(
1129 set_w == 0 &&
1130 set_h == 0 &&
1131 set_presentation_mode == SDL_LOGICAL_PRESENTATION_DISABLED,
1132 "Validate result from SDL_GetRenderLogicalPresentation, got %d, %d, %d", set_w, set_h, set_presentation_mode);
1133 CHECK_FUNC(SDL_GetRenderLogicalPresentationRect, (renderer, &set_rect))
1134 SDLTest_AssertCheck(
1135 set_rect.x == 0.0f &&
1136 set_rect.y == 0.0f &&
1137 set_rect.w == 320.0f &&
1138 set_rect.h == 240.0f,
1139 "Validate result from SDL_GetRenderLogicalPresentationRect, got {%g, %g, %gx%g}", set_rect.x, set_rect.y, set_rect.w, set_rect.h);
1140
1141 /* Check to see if final image matches. */
1142 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
1143
1144 /* Clear surface. */
1145 clearScreen();
1146
1147 /* Set the logical size and viewport and do a fill operation */
1148 CHECK_FUNC(SDL_GetCurrentRenderOutputSize, (renderer, &w, &h))
1149 CHECK_FUNC(SDL_SetRenderLogicalPresentation, (renderer, w / factor, h / factor, SDL_LOGICAL_PRESENTATION_LETTERBOX))
1150 viewport.x = (TESTRENDER_SCREEN_W / 4) / factor;
1151 viewport.y = (TESTRENDER_SCREEN_H / 4) / factor;
1152 viewport.w = (TESTRENDER_SCREEN_W / 2) / factor;
1153 viewport.h = (TESTRENDER_SCREEN_H / 2) / factor;
1154 CHECK_FUNC(SDL_SetRenderViewport, (renderer, &viewport))
1155 CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 0, 255, 0, SDL_ALPHA_OPAQUE))
1156 CHECK_FUNC(SDL_RenderFillRect, (renderer, NULL))
1157 CHECK_FUNC(SDL_SetRenderViewport, (renderer, NULL))
1158 CHECK_FUNC(SDL_SetRenderLogicalPresentation, (renderer, 0, 0, SDL_LOGICAL_PRESENTATION_DISABLED))
1159
1160 /* Check to see if final image matches. */
1161 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
1162
1163 /*
1164 * Test a logical size that isn't the same aspect ratio as the window
1165 */
1166
1167 viewport.x = (TESTRENDER_SCREEN_W / 4);
1168 viewport.y = 0;
1169 viewport.w = TESTRENDER_SCREEN_W;
1170 viewport.h = TESTRENDER_SCREEN_H;
1171
1172 /* Create expected result */
1173 CHECK_FUNC(SDL_FillSurfaceRect, (referenceSurface, NULL, RENDER_COLOR_CLEAR))
1174 CHECK_FUNC(SDL_FillSurfaceRect, (referenceSurface, &viewport, RENDER_COLOR_GREEN))
1175
1176 /* Clear surface. */
1177 clearScreen();
1178
1179 /* Set the logical size and do a fill operation */
1180 CHECK_FUNC(SDL_GetCurrentRenderOutputSize, (renderer, &w, &h))
1181 CHECK_FUNC(SDL_SetRenderLogicalPresentation, (renderer,
1182 w - 2 * (TESTRENDER_SCREEN_W / 4),
1183 h,
1184 SDL_LOGICAL_PRESENTATION_LETTERBOX))
1185 CHECK_FUNC(SDL_GetRenderLogicalPresentation, (renderer, &set_w, &set_h, &set_presentation_mode))
1186 SDLTest_AssertCheck(
1187 set_w == w - 2 * (TESTRENDER_SCREEN_W / 4) &&
1188 set_h == h &&
1189 set_presentation_mode == SDL_LOGICAL_PRESENTATION_LETTERBOX,
1190 "Validate result from SDL_GetRenderLogicalPresentation, got %d, %d, %d", set_w, set_h, set_presentation_mode);
1191 CHECK_FUNC(SDL_GetRenderLogicalPresentationRect, (renderer, &set_rect))
1192 SDLTest_AssertCheck(
1193 set_rect.x == 20.0f &&
1194 set_rect.y == 0.0f &&
1195 set_rect.w == 280.0f &&
1196 set_rect.h == 240.0f,
1197 "Validate result from SDL_GetRenderLogicalPresentationRect, got {%g, %g, %gx%g}", set_rect.x, set_rect.y, set_rect.w, set_rect.h);
1198 CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 0, 255, 0, SDL_ALPHA_OPAQUE))
1199 CHECK_FUNC(SDL_RenderFillRect, (renderer, NULL))
1200 CHECK_FUNC(SDL_SetRenderLogicalPresentation, (renderer, 0, 0, SDL_LOGICAL_PRESENTATION_DISABLED))
1201 CHECK_FUNC(SDL_GetRenderLogicalPresentation, (renderer, &set_w, &set_h, &set_presentation_mode))
1202 SDLTest_AssertCheck(
1203 set_w == 0 &&
1204 set_h == 0 &&
1205 set_presentation_mode == SDL_LOGICAL_PRESENTATION_DISABLED,
1206 "Validate result from SDL_GetRenderLogicalPresentation, got %d, %d, %d", set_w, set_h, set_presentation_mode);
1207 CHECK_FUNC(SDL_GetRenderLogicalPresentationRect, (renderer, &set_rect))
1208 SDLTest_AssertCheck(
1209 set_rect.x == 0.0f &&
1210 set_rect.y == 0.0f &&
1211 set_rect.w == 320.0f &&
1212 set_rect.h == 240.0f,
1213 "Validate result from SDL_GetRenderLogicalPresentationRect, got {%g, %g, %gx%g}", set_rect.x, set_rect.y, set_rect.w, set_rect.h);
1214
1215 /* Check to see if final image matches. */
1216 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
1217
1218 /* Clear surface. */
1219 clearScreen();
1220
1221 /* Make current */
1222 SDL_RenderPresent(renderer);
1223
1224 SDL_DestroySurface(referenceSurface);
1225
1226 return TEST_COMPLETED;
1227}
1228
1229/* Helper functions */
1230
1231/**
1232 * Checks to see if functionality is supported. Helper function.
1233 */
1234static bool isSupported(int code)
1235{
1236 return (code != false);
1237}
1238
1239/**
1240 * Test to see if we can vary the draw color. Helper function.
1241 *
1242 * \sa SDL_SetRenderDrawColor
1243 * \sa SDL_GetRenderDrawColor
1244 */
1245static bool hasDrawColor(void)
1246{
1247 int ret, fail;
1248 Uint8 r, g, b, a;
1249
1250 fail = 0;
1251
1252 /* Set color. */
1253 ret = SDL_SetRenderDrawColor(renderer, 100, 100, 100, 100);
1254 if (!isSupported(ret)) {
1255 fail = 1;
1256 }
1257 ret = SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a);
1258 if (!isSupported(ret)) {
1259 fail = 1;
1260 }
1261
1262 /* Restore natural. */
1263 ret = SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
1264 if (!isSupported(ret)) {
1265 fail = 1;
1266 }
1267
1268 /* Something failed, consider not available. */
1269 if (fail) {
1270 return false;
1271 }
1272 /* Not set properly, consider failed. */
1273 else if ((r != 100) || (g != 100) || (b != 100) || (a != 100)) {
1274 return false;
1275 }
1276 return true;
1277}
1278
1279/**
1280 * Loads the test image 'Face' as texture. Helper function.
1281 *
1282 * \sa SDL_CreateTextureFromSurface
1283 */
1284static SDL_Texture *
1285loadTestFace(void)
1286{
1287 SDL_Surface *face;
1288 SDL_Texture *tface;
1289
1290 face = SDLTest_ImageFace();
1291 if (!face) {
1292 return NULL;
1293 }
1294
1295 tface = SDL_CreateTextureFromSurface(renderer, face);
1296 if (!tface) {
1297 SDLTest_LogError("SDL_CreateTextureFromSurface() failed with error: %s", SDL_GetError());
1298 }
1299
1300 SDL_DestroySurface(face);
1301
1302 return tface;
1303}
1304
1305/**
1306 * Compares screen pixels with image pixels. Helper function.
1307 *
1308 * \param referenceSurface Image to compare against.
1309 * \param allowable_error allowed difference from the reference image
1310 *
1311 * \sa SDL_RenderReadPixels
1312 * \sa SDL_CreateSurfaceFrom
1313 * \sa SDL_DestroySurface
1314 */
1315static void compare(SDL_Surface *referenceSurface, int allowable_error)
1316{
1317 int ret;
1318 SDL_Rect rect;
1319 SDL_Surface *surface, *testSurface;
1320
1321 /* Explicitly specify the rect in case the window isn't the expected size... */
1322 rect.x = 0;
1323 rect.y = 0;
1324 rect.w = TESTRENDER_SCREEN_W;
1325 rect.h = TESTRENDER_SCREEN_H;
1326
1327 surface = SDL_RenderReadPixels(renderer, &rect);
1328 if (!surface) {
1329 SDLTest_AssertCheck(surface != NULL, "Validate result from SDL_RenderReadPixels, got NULL, %s", SDL_GetError());
1330 return;
1331 }
1332
1333 testSurface = SDL_ConvertSurface(surface, RENDER_COMPARE_FORMAT);
1334 SDL_DestroySurface(surface);
1335 if (!testSurface) {
1336 SDLTest_AssertCheck(testSurface != NULL, "Validate result from SDL_ConvertSurface, got NULL, %s", SDL_GetError());
1337 return;
1338 }
1339
1340 /* Compare surface. */
1341 ret = SDLTest_CompareSurfaces(testSurface, referenceSurface, allowable_error);
1342 SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
1343
1344 /* Clean up. */
1345 SDL_DestroySurface(testSurface);
1346}
1347static void compare2x(SDL_Surface *referenceSurface, int allowable_error)
1348{
1349 int ret;
1350 SDL_Rect rect;
1351 SDL_Surface *surface, *testSurface;
1352
1353 /* Explicitly specify the rect in case the window isn't the expected size... */
1354 rect.x = 0;
1355 rect.y = 0;
1356 rect.w = TESTRENDER_SCREEN_W * 2;
1357 rect.h = TESTRENDER_SCREEN_H * 2;
1358
1359 surface = SDL_RenderReadPixels(renderer, &rect);
1360 if (!surface) {
1361 SDLTest_AssertCheck(surface != NULL, "Validate result from SDL_RenderReadPixels, got NULL, %s", SDL_GetError());
1362 return;
1363 }
1364
1365 testSurface = SDL_ConvertSurface(surface, RENDER_COMPARE_FORMAT);
1366 SDL_DestroySurface(surface);
1367 if (!testSurface) {
1368 SDLTest_AssertCheck(testSurface != NULL, "Validate result from SDL_ConvertSurface, got NULL, %s", SDL_GetError());
1369 return;
1370 }
1371
1372 /* Compare surface. */
1373 ret = SDLTest_CompareSurfaces(testSurface, referenceSurface, allowable_error);
1374 SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
1375
1376 /* Clean up. */
1377 SDL_DestroySurface(testSurface);
1378}
1379
1380/**
1381 * Clears the screen. Helper function.
1382 *
1383 * \sa SDL_SetRenderDrawColor
1384 * \sa SDL_RenderClear
1385 * \sa SDL_RenderPresent
1386 * \sa SDL_SetRenderDrawBlendMode
1387 */
1388static int
1389clearScreen(void)
1390{
1391 int ret;
1392
1393 /* Make current */
1394 SDL_RenderPresent(renderer);
1395
1396 /* Set color. */
1397 ret = SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
1398 SDLTest_AssertCheck(ret == true, "Validate result from SDL_SetRenderDrawColor, expected: true, got: %i", ret);
1399
1400 /* Clear screen. */
1401 ret = SDL_RenderClear(renderer);
1402 SDLTest_AssertCheck(ret == true, "Validate result from SDL_RenderClear, expected: true, got: %i", ret);
1403
1404 /* Set defaults. */
1405 ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
1406 SDLTest_AssertCheck(ret == true, "Validate result from SDL_SetRenderDrawBlendMode, expected: true, got: %i", ret);
1407
1408 ret = SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
1409 SDLTest_AssertCheck(ret == true, "Validate result from SDL_SetRenderDrawColor, expected: true, got: %i", ret);
1410
1411 return 0;
1412}
1413
1414/**
1415 * Tests geometry UV wrapping
1416 */
1417static int SDLCALL render_testUVWrapping(void *arg)
1418{
1419 SDL_Vertex vertices[6];
1420 SDL_Vertex *verts = vertices;
1421 SDL_FColor color = { 1.0f, 1.0f, 1.0f, 1.0f };
1422 SDL_FRect rect;
1423 float min_U = -0.5f;
1424 float max_U = 1.5f;
1425 float min_V = -0.5f;
1426 float max_V = 1.5f;
1427 SDL_Texture *tface;
1428 SDL_Surface *referenceSurface = NULL;
1429
1430 /* Clear surface. */
1431 clearScreen();
1432
1433 /* Create face surface. */
1434 tface = loadTestFace();
1435 SDLTest_AssertCheck(tface != NULL, "Verify loadTestFace() result");
1436 if (tface == NULL) {
1437 return TEST_ABORTED;
1438 }
1439
1440 rect.w = (float)tface->w * 2;
1441 rect.h = (float)tface->h * 2;
1442 rect.x = (TESTRENDER_SCREEN_W - rect.w) / 2;
1443 rect.y = (TESTRENDER_SCREEN_H - rect.h) / 2;
1444
1445 /*
1446 * 0--1
1447 * | /|
1448 * |/ |
1449 * 3--2
1450 *
1451 * Draw sprite2 as triangles that can be recombined as rect by software renderer
1452 */
1453
1454 /* 0 */
1455 verts->position.x = rect.x;
1456 verts->position.y = rect.y;
1457 verts->color = color;
1458 verts->tex_coord.x = min_U;
1459 verts->tex_coord.y = min_V;
1460 verts++;
1461 /* 1 */
1462 verts->position.x = rect.x + rect.w;
1463 verts->position.y = rect.y;
1464 verts->color = color;
1465 verts->tex_coord.x = max_U;
1466 verts->tex_coord.y = min_V;
1467 verts++;
1468 /* 2 */
1469 verts->position.x = rect.x + rect.w;
1470 verts->position.y = rect.y + rect.h;
1471 verts->color = color;
1472 verts->tex_coord.x = max_U;
1473 verts->tex_coord.y = max_V;
1474 verts++;
1475 /* 0 */
1476 verts->position.x = rect.x;
1477 verts->position.y = rect.y;
1478 verts->color = color;
1479 verts->tex_coord.x = min_U;
1480 verts->tex_coord.y = min_V;
1481 verts++;
1482 /* 2 */
1483 verts->position.x = rect.x + rect.w;
1484 verts->position.y = rect.y + rect.h;
1485 verts->color = color;
1486 verts->tex_coord.x = max_U;
1487 verts->tex_coord.y = max_V;
1488 verts++;
1489 /* 3 */
1490 verts->position.x = rect.x;
1491 verts->position.y = rect.y + rect.h;
1492 verts->color = color;
1493 verts->tex_coord.x = min_U;
1494 verts->tex_coord.y = max_V;
1495 verts++;
1496
1497 /* Blit sprites as triangles onto the screen */
1498 SDL_RenderGeometry(renderer, tface, vertices, 6, NULL, 0);
1499
1500 /* See if it's the same */
1501 referenceSurface = SDLTest_ImageWrappingSprite();
1502 compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
1503
1504 /* Make current */
1505 SDL_RenderPresent(renderer);
1506
1507 /* Clean up. */
1508 SDL_DestroyTexture(tface);
1509 SDL_DestroySurface(referenceSurface);
1510 referenceSurface = NULL;
1511
1512 return TEST_COMPLETED;
1513}
1514
1515/**
1516 * Tests texture state changes
1517 */
1518static int SDLCALL render_testTextureState(void *arg)
1519{
1520 const Uint8 pixels[8] = {
1521 0x00, 0x00, 0x00, 0xFF,
1522 0xFF, 0xFF, 0xFF, 0xFF
1523 };
1524 const SDL_Color expected[] = {
1525 /* Step 0: plain copy */
1526 { 0x00, 0x00, 0x00, 0xFF },
1527 { 0xFF, 0xFF, 0xFF, 0xFF },
1528 /* Step 1: color mod to red */
1529 { 0x00, 0x00, 0x00, 0xFF },
1530 { 0xFF, 0x00, 0x00, 0xFF },
1531 /* Step 2: alpha mod to 128 (cleared to green) */
1532 { 0x00, 0x7F, 0x00, 0xFF },
1533 { 0x80, 0xFF, 0x80, 0xFF },
1534 /* Step 3: nearest stretch */
1535 { 0xFF, 0xFF, 0xFF, 0xFF },
1536 { 0x00, 0xFF, 0x00, 0xFF },
1537 /* Step 4: linear stretch */
1538 { 0x80, 0x80, 0x80, 0xFF },
1539 { 0x00, 0xFF, 0x00, 0xFF },
1540 };
1541 SDL_Texture *texture;
1542 SDL_Rect rect;
1543 SDL_FRect dst;
1544 int i;
1545
1546 /* Clear surface to green */
1547 SDL_SetRenderDrawColor(renderer, 0, 255, 0, SDL_ALPHA_OPAQUE);
1548 SDL_RenderClear(renderer);
1549
1550 /* Create 2-pixel surface. */
1551 texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, 2, 1);
1552 SDLTest_AssertCheck(texture != NULL, "Verify SDL_CreateTexture() result");
1553 if (texture == NULL) {
1554 return TEST_ABORTED;
1555 }
1556 SDL_UpdateTexture(texture, NULL, pixels, sizeof(pixels));
1557
1558 dst.x = 0.0f;
1559 dst.y = 0.0f;
1560 dst.w = 2.0f;
1561 dst.h = 1.0f;
1562
1563 /* Step 0: plain copy */
1564 SDL_RenderTexture(renderer, texture, NULL, &dst);
1565 dst.y += 1;
1566
1567 /* Step 1: color mod to red */
1568 SDL_SetTextureColorMod(texture, 0xFF, 0x00, 0x00);
1569 SDL_RenderTexture(renderer, texture, NULL, &dst);
1570 SDL_SetTextureColorMod(texture, 0xFF, 0xFF, 0xFF);
1571 dst.y += 1;
1572
1573 /* Step 2: alpha mod to 128 */
1574 SDL_SetTextureAlphaMod(texture, 0x80);
1575 SDL_RenderTexture(renderer, texture, NULL, &dst);
1576 SDL_SetTextureAlphaMod(texture, 0xFF);
1577 dst.y += 1;
1578
1579 /* Step 3: nearest stretch */
1580 dst.w = 1;
1581 SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST);
1582 SDL_RenderTexture(renderer, texture, NULL, &dst);
1583 dst.y += 1;
1584
1585 /* Step 4: linear stretch */
1586 dst.w = 1;
1587 SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_LINEAR);
1588 SDL_RenderTexture(renderer, texture, NULL, &dst);
1589 dst.y += 1;
1590
1591 /* Verify results */
1592 rect.x = 0;
1593 rect.y = 0;
1594 rect.w = 2;
1595 rect.h = 1;
1596 for (i = 0; i < SDL_arraysize(expected); ) {
1597 const int MAX_DELTA = 1;
1598 SDL_Color actual;
1599 int deltaR, deltaG, deltaB, deltaA;
1600 SDL_Surface *surface = SDL_RenderReadPixels(renderer, &rect);
1601
1602 SDL_ReadSurfacePixel(surface, 0, 0, &actual.r, &actual.g, &actual.b, &actual.a);
1603 deltaR = (actual.r - expected[i].r);
1604 deltaG = (actual.g - expected[i].g);
1605 deltaB = (actual.b - expected[i].b);
1606 deltaA = (actual.a - expected[i].a);
1607 SDLTest_AssertCheck(SDL_abs(deltaR) <= MAX_DELTA &&
1608 SDL_abs(deltaG) <= MAX_DELTA &&
1609 SDL_abs(deltaB) <= MAX_DELTA &&
1610 SDL_abs(deltaA) <= MAX_DELTA,
1611 "Validate left pixel at step %d, expected %d,%d,%d,%d, got %d,%d,%d,%d", i/2,
1612 expected[i].r, expected[i].g, expected[i].b, expected[i].a,
1613 actual.r, actual.g, actual.b, actual.a);
1614 ++i;
1615
1616 SDL_ReadSurfacePixel(surface, 1, 0, &actual.r, &actual.g, &actual.b, &actual.a);
1617 deltaR = (actual.r - expected[i].r);
1618 deltaG = (actual.g - expected[i].g);
1619 deltaB = (actual.b - expected[i].b);
1620 deltaA = (actual.a - expected[i].a);
1621 SDLTest_AssertCheck(SDL_abs(deltaR) <= MAX_DELTA &&
1622 SDL_abs(deltaG) <= MAX_DELTA &&
1623 SDL_abs(deltaB) <= MAX_DELTA &&
1624 SDL_abs(deltaA) <= MAX_DELTA,
1625 "Validate right pixel at step %d, expected %d,%d,%d,%d, got %d,%d,%d,%d", i/2,
1626 expected[i].r, expected[i].g, expected[i].b, expected[i].a,
1627 actual.r, actual.g, actual.b, actual.a);
1628 ++i;
1629
1630 SDL_DestroySurface(surface);
1631
1632 rect.y += 1;
1633 }
1634
1635 /* Clean up. */
1636 SDL_DestroyTexture(texture);
1637
1638 return TEST_COMPLETED;
1639}
1640
1641/* ================= Test References ================== */
1642
1643/* Render test cases */
1644static const SDLTest_TestCaseReference renderTestGetNumRenderDrivers = {
1645 render_testGetNumRenderDrivers, "render_testGetNumRenderDrivers", "Tests call to SDL_GetNumRenderDrivers", TEST_ENABLED
1646};
1647
1648static const SDLTest_TestCaseReference renderTestPrimitives = {
1649 render_testPrimitives, "render_testPrimitives", "Tests rendering primitives", TEST_ENABLED
1650};
1651
1652static const SDLTest_TestCaseReference renderTestPrimitivesWithViewport = {
1653 render_testPrimitivesWithViewport, "render_testPrimitivesWithViewport", "Tests rendering primitives within a viewport", TEST_ENABLED
1654};
1655
1656static const SDLTest_TestCaseReference renderTestBlit = {
1657 render_testBlit, "render_testBlit", "Tests blitting", TEST_ENABLED
1658};
1659
1660static const SDLTest_TestCaseReference renderTestBlitTiled = {
1661 render_testBlitTiled, "render_testBlitTiled", "Tests tiled blitting", TEST_ENABLED
1662};
1663
1664static const SDLTest_TestCaseReference renderTestBlit9Grid = {
1665 render_testBlit9Grid, "render_testBlit9Grid", "Tests 9-grid blitting", TEST_ENABLED
1666};
1667
1668static const SDLTest_TestCaseReference renderTestBlitColor = {
1669 render_testBlitColor, "render_testBlitColor", "Tests blitting with color", TEST_ENABLED
1670};
1671
1672static const SDLTest_TestCaseReference renderTestBlendModes = {
1673 render_testBlendModes, "render_testBlendModes", "Tests rendering blend modes", TEST_ENABLED
1674};
1675
1676static const SDLTest_TestCaseReference renderTestViewport = {
1677 render_testViewport, "render_testViewport", "Tests viewport", TEST_ENABLED
1678};
1679
1680static const SDLTest_TestCaseReference renderTestClipRect = {
1681 render_testClipRect, "render_testClipRect", "Tests clip rect", TEST_ENABLED
1682};
1683
1684static const SDLTest_TestCaseReference renderTestLogicalSize = {
1685 render_testLogicalSize, "render_testLogicalSize", "Tests logical size", TEST_ENABLED
1686};
1687
1688static const SDLTest_TestCaseReference renderTestUVWrapping = {
1689 render_testUVWrapping, "render_testUVWrapping", "Tests geometry UV wrapping", TEST_ENABLED
1690};
1691
1692static const SDLTest_TestCaseReference renderTestTextureState = {
1693 render_testTextureState, "render_testTextureState", "Tests texture state changes", TEST_ENABLED
1694};
1695
1696/* Sequence of Render test cases */
1697static const SDLTest_TestCaseReference *renderTests[] = {
1698 &renderTestGetNumRenderDrivers,
1699 &renderTestPrimitives,
1700 &renderTestPrimitivesWithViewport,
1701 &renderTestBlit,
1702 &renderTestBlitTiled,
1703 &renderTestBlit9Grid,
1704 &renderTestBlitColor,
1705 &renderTestBlendModes,
1706 &renderTestViewport,
1707 &renderTestClipRect,
1708 &renderTestLogicalSize,
1709 &renderTestUVWrapping,
1710 &renderTestTextureState,
1711 NULL
1712};
1713
1714/* Render test suite (global) */
1715SDLTest_TestSuiteReference renderTestSuite = {
1716 "Render",
1717 InitCreateRenderer,
1718 renderTests,
1719 CleanupDestroyRenderer
1720};