summaryrefslogtreecommitdiff
path: root/src/contrib/SDL-3.2.20/test/testautomation_blit.c
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-08-30 16:53:58 -0700
committer3gg <3gg@shellblade.net>2025-08-30 16:53:58 -0700
commit6aaedb813fa11ba0679c3051bc2eb28646b9506c (patch)
tree34acbfc9840e02cb4753e6306ea7ce978bf8b58e /src/contrib/SDL-3.2.20/test/testautomation_blit.c
parent8f228ade99dd3d4c8da9b78ade1815c9adf85c8f (diff)
Update to SDL3
Diffstat (limited to 'src/contrib/SDL-3.2.20/test/testautomation_blit.c')
-rw-r--r--src/contrib/SDL-3.2.20/test/testautomation_blit.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/test/testautomation_blit.c b/src/contrib/SDL-3.2.20/test/testautomation_blit.c
new file mode 100644
index 0000000..a461005
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/test/testautomation_blit.c
@@ -0,0 +1,215 @@
1/**
2 * SDL_BlitSurface bit-perfect rendering test suite written by Isaac Aronson
3 */
4
5/* Suppress C4996 VS compiler warnings for unlink() */
6#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
7#define _CRT_SECURE_NO_DEPRECATE
8#endif
9#if defined(_MSC_VER) && !defined(_CRT_NONSTDC_NO_DEPRECATE)
10#define _CRT_NONSTDC_NO_DEPRECATE
11#endif
12
13#include <stdio.h>
14#ifndef _MSC_VER
15#include <unistd.h>
16#else
17/* Suppress uint64 to uint32 conversion warning within the PRNG engine */
18#pragma warning( disable : 4244 )
19#endif
20#include <sys/stat.h>
21
22#include <SDL3/SDL.h>
23#include <SDL3/SDL_test.h>
24#include "testautomation_images.h"
25
26/* ====== xoroshiro128+ PRNG engine for deterministic blit input ===== */
27Uint64 rotl(Uint64 x, int k) { return (x << k) | (x >> (-k & 63)); }
28Uint64 next(Uint64 state[2]) {
29 Uint64 s0 = state[0], s1 = state[1];
30 Uint64 result = rotl((s0 + s1) * 9, 29) + s0;
31 state[0] = s0 ^ rotl(s1, 29);
32 state[1] = s0 ^ s1 << 9;
33 return result;
34}
35static Uint64 rngState[2] = {1, 2};
36Uint32 getRandomUint32(void) {
37 return (Uint32)next(rngState);
38}
39/* ================= Test Case Helper Functions ================== */
40/*
41 * Resets PRNG state to initialize tests using PRNG
42 */
43void SDLCALL blitSetUp(void **arg) {
44 rngState[0] = 1;
45 rngState[1] = 2;
46}
47/*
48 * Fill buffer with stream of PRNG pixel data given size
49 */
50static Uint32 *fillNextRandomBuffer(Uint32 *buf, const int width, const int height) {
51 int i;
52 for (i = 0; i < width * height; i++) {
53 buf[i] = getRandomUint32();
54 }
55 return buf;
56}
57/*
58 * Generates a stream of PRNG pixel data given length
59 */
60static Uint32 *getNextRandomBuffer(const int width, const int height) {
61 Uint32* buf = SDL_malloc(sizeof(Uint32) * width * height);
62 fillNextRandomBuffer(buf, width, height);
63 return buf;
64}
65/*
66 * Generates a 800 x 600 surface of PRNG pixel data
67 */
68SDL_Surface* getRandomSVGASurface(Uint32 *pixels, SDL_PixelFormat format) {
69 return SDL_CreateSurfaceFrom(800, 600, format, pixels, 800 * 4);
70}
71/*
72 * Calculates the FNV-1a hash of input pixel data
73 */
74Uint32 FNVHash(Uint32* buf, int length) {
75 const Uint32 fnv_prime = 0x811C9DC5;
76 Uint32 hash = 0;
77 int i;
78
79 for (i = 0; i < length; buf++, i++)
80 {
81 hash *= fnv_prime;
82 hash ^= (*buf);
83 }
84
85 return hash;
86}
87/*
88 * Wraps the FNV-1a hash for an input surface's pixels
89 */
90Uint32 hashSurfacePixels(SDL_Surface * surface) {
91 Uint64 buffer_size = surface->w * surface->h;
92 return FNVHash(surface->pixels, buffer_size);
93}
94/* ================= Test Case Implementation ================== */
95/**
96 * Tests rendering a rainbow gradient background onto a blank surface, then rendering a sprite with complex geometry and
97 * transparency on top of said surface, and comparing the result to known accurate renders with a hash.
98 */
99static int SDLCALL blit_testExampleApplicationRender(void *arg) {
100 const int width = 32;
101 const int height = 32;
102 const Uint32 correct_hash = 0xe345d7a7;
103 SDL_Surface* dest_surface = SDL_CreateSurface(width, height, SDL_PIXELFORMAT_ARGB8888);
104 SDL_Surface* rainbow_background = SDLTest_ImageBlendingBackground();
105 SDL_Surface* gearbrain_sprite = SDLTest_ImageBlendingSprite();
106 // Blit background into "screen"
107 SDL_BlitSurface(rainbow_background, NULL, dest_surface, NULL);
108 // Blit example game sprite onto "screen"
109 SDL_BlitSurface(gearbrain_sprite, NULL, dest_surface, NULL);
110 // Check result
111 const Uint32 hash = hashSurfacePixels(dest_surface);
112 SDLTest_AssertCheck(hash == correct_hash,
113 "Should render identically, expected hash 0x%" SDL_PRIx32 ", got 0x%" SDL_PRIx32,
114 correct_hash, hash);
115 // Clean up
116 SDL_DestroySurface(rainbow_background);
117 SDL_DestroySurface(gearbrain_sprite);
118 SDL_DestroySurface(dest_surface);
119 return TEST_COMPLETED;
120}
121/**
122 * Tests rendering PRNG noise onto a surface of PRNG noise, while also testing color shift operations between the
123 * different source and destination pixel formats, without an alpha shuffle, at SVGA resolution. Compares to known
124 * accurate renders with a hash.
125 */
126static int SDLCALL blit_testRandomToRandomSVGA(void *arg) {
127 const int width = 800;
128 const int height = 600;
129 const Uint32 correct_hash = 0x42140c5f;
130 // Allocate random buffers
131 Uint32 *dest_pixels = getNextRandomBuffer(width, height);
132 Uint32 *src_pixels = getNextRandomBuffer(width, height);
133 // Create surfaces of different pixel formats
134 SDL_Surface* dest_surface = getRandomSVGASurface(dest_pixels, SDL_PIXELFORMAT_BGRA8888);
135 SDL_Surface* src_surface = getRandomSVGASurface(src_pixels, SDL_PIXELFORMAT_RGBA8888);
136 // Blit surfaces
137 SDL_BlitSurface(src_surface, NULL, dest_surface, NULL);
138 // Check result
139 const Uint32 hash = hashSurfacePixels(dest_surface);
140 SDLTest_AssertCheck(hash == correct_hash,
141 "Should render identically, expected hash 0x%" SDL_PRIx32 ", got 0x%" SDL_PRIx32,
142 correct_hash, hash);
143 // Clean up
144 SDL_DestroySurface(dest_surface);
145 SDL_DestroySurface(src_surface);
146 SDL_free(dest_pixels);
147 SDL_free(src_pixels);
148 return TEST_COMPLETED;
149}
150/**
151 * Tests rendering small chunks of 15 by 15px PRNG noise onto an initially blank SVGA surface, while also testing color
152 * shift operations between the different source and destination pixel formats, including an alpha shuffle. Compares to
153 * known accurate renders with a hash.
154 */
155static int SDLCALL blit_testRandomToRandomSVGAMultipleIterations(void *arg) {
156 const int width = 800;
157 const int height = 600;
158 const int blit_width = 15;
159 const int blit_height = 15;
160 int i;
161 const Uint32 correct_hash = 0x5d26be78;
162 Uint32 *buf = SDL_malloc(blit_width * blit_height * sizeof(Uint32));
163 // Create blank source surface
164 SDL_Surface *sourceSurface = SDL_CreateSurface(blit_width, blit_height, SDL_PIXELFORMAT_RGBA8888);
165 // Create blank destination surface
166 SDL_Surface* dest_surface = SDL_CreateSurface(width, height, SDL_PIXELFORMAT_ABGR8888);
167
168 // Perform 250k random blits into random areas of the blank surface
169 for (i = 0; i < 250000; i++) {
170 fillNextRandomBuffer(buf, blit_width, blit_height);
171 SDL_LockSurface(sourceSurface);
172 SDL_memcpy(sourceSurface->pixels, buf, blit_width * blit_height * sizeof(Uint32));
173 SDL_UnlockSurface(sourceSurface);
174
175 SDL_Rect dest_rect;
176 int location = (int)getRandomUint32();
177 dest_rect.x = location % (width - 15 - 1);
178 dest_rect.y = location % (height - 15 - 1);
179
180 SDL_BlitSurface(sourceSurface, NULL, dest_surface, &dest_rect);
181 }
182 // Check result
183 const Uint32 hash = hashSurfacePixels(dest_surface);
184 // Clean up
185 SDL_DestroySurface(dest_surface);
186 SDLTest_AssertCheck(hash == correct_hash,
187 "Should render identically, expected hash 0x%" SDL_PRIx32 ", got 0x%" SDL_PRIx32,
188 correct_hash, hash);
189 SDL_DestroySurface(sourceSurface);
190 SDL_free(buf);
191 return TEST_COMPLETED;
192}
193
194static const SDLTest_TestCaseReference blitTest1 = {
195 blit_testExampleApplicationRender, "blit_testExampleApplicationRender",
196 "Test example application render.", TEST_ENABLED
197};
198static const SDLTest_TestCaseReference blitTest2 = {
199 blit_testRandomToRandomSVGA, "blit_testRandomToRandomSVGA",
200 "Test SVGA noise render.", TEST_ENABLED
201};
202static const SDLTest_TestCaseReference blitTest3 = {
203 blit_testRandomToRandomSVGAMultipleIterations, "blit_testRandomToRandomSVGAMultipleIterations",
204 "Test SVGA noise render (250k iterations).", TEST_ENABLED
205};
206static const SDLTest_TestCaseReference *blitTests[] = {
207 &blitTest1, &blitTest2, &blitTest3, NULL
208};
209
210SDLTest_TestSuiteReference blitTestSuite = {
211 "Blending",
212 blitSetUp,
213 blitTests,
214 NULL
215};