Atlas - testautomation_blit.c
Home / ext / SDL / test Lines: 1 | Size: 7994 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]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 int buffer_size = surface->w * surface->h; 92 if (buffer_size < 0) { 93 return 0; 94 } 95 return FNVHash(surface->pixels, buffer_size); 96} 97/* ================= Test Case Implementation ================== */ 98/** 99 * Tests rendering a rainbow gradient background onto a blank surface, then rendering a sprite with complex geometry and 100 * transparency on top of said surface, and comparing the result to known accurate renders with a hash. 101 */ 102static int SDLCALL blit_testExampleApplicationRender(void *arg) { 103 const int width = 32; 104 const int height = 32; 105 const Uint32 correct_hash = 0xe345d7a7; 106 SDL_Surface* dest_surface = SDL_CreateSurface(width, height, SDL_PIXELFORMAT_ARGB8888); 107 SDL_Surface* rainbow_background = SDLTest_ImageBlendingBackground(); 108 SDL_Surface* gearbrain_sprite = SDLTest_ImageBlendingSprite(); 109 // Blit background into "screen" 110 SDL_BlitSurface(rainbow_background, NULL, dest_surface, NULL); 111 // Blit example game sprite onto "screen" 112 SDL_BlitSurface(gearbrain_sprite, NULL, dest_surface, NULL); 113 // Check result 114 const Uint32 hash = hashSurfacePixels(dest_surface); 115 SDLTest_AssertCheck(hash == correct_hash, 116 "Should render identically, expected hash 0x%" SDL_PRIx32 ", got 0x%" SDL_PRIx32, 117 correct_hash, hash); 118 // Clean up 119 SDL_DestroySurface(rainbow_background); 120 SDL_DestroySurface(gearbrain_sprite); 121 SDL_DestroySurface(dest_surface); 122 return TEST_COMPLETED; 123} 124/** 125 * Tests rendering PRNG noise onto a surface of PRNG noise, while also testing color shift operations between the 126 * different source and destination pixel formats, without an alpha shuffle, at SVGA resolution. Compares to known 127 * accurate renders with a hash. 128 */ 129static int SDLCALL blit_testRandomToRandomSVGA(void *arg) { 130 const int width = 800; 131 const int height = 600; 132 const Uint32 correct_hash = 0x42140c5f; 133 // Allocate random buffers 134 Uint32 *dest_pixels = getNextRandomBuffer(width, height); 135 Uint32 *src_pixels = getNextRandomBuffer(width, height); 136 // Create surfaces of different pixel formats 137 SDL_Surface* dest_surface = getRandomSVGASurface(dest_pixels, SDL_PIXELFORMAT_BGRA8888); 138 SDL_Surface* src_surface = getRandomSVGASurface(src_pixels, SDL_PIXELFORMAT_RGBA8888); 139 // Blit surfaces 140 SDL_BlitSurface(src_surface, NULL, dest_surface, NULL); 141 // Check result 142 const Uint32 hash = hashSurfacePixels(dest_surface); 143 SDLTest_AssertCheck(hash == correct_hash, 144 "Should render identically, expected hash 0x%" SDL_PRIx32 ", got 0x%" SDL_PRIx32, 145 correct_hash, hash); 146 // Clean up 147 SDL_DestroySurface(dest_surface); 148 SDL_DestroySurface(src_surface); 149 SDL_free(dest_pixels); 150 SDL_free(src_pixels); 151 return TEST_COMPLETED; 152} 153/** 154 * Tests rendering small chunks of 15 by 15px PRNG noise onto an initially blank SVGA surface, while also testing color 155 * shift operations between the different source and destination pixel formats, including an alpha shuffle. Compares to 156 * known accurate renders with a hash. 157 */ 158static int SDLCALL blit_testRandomToRandomSVGAMultipleIterations(void *arg) { 159 const int width = 800; 160 const int height = 600; 161 const int blit_width = 15; 162 const int blit_height = 15; 163 int i; 164 const Uint32 correct_hash = 0x5d26be78; 165 Uint32 *buf = SDL_malloc(blit_width * blit_height * sizeof(Uint32)); 166 // Create blank source surface 167 SDL_Surface *sourceSurface = SDL_CreateSurface(blit_width, blit_height, SDL_PIXELFORMAT_RGBA8888); 168 // Create blank destination surface 169 SDL_Surface* dest_surface = SDL_CreateSurface(width, height, SDL_PIXELFORMAT_ABGR8888); 170 171 // Perform 250k random blits into random areas of the blank surface 172 for (i = 0; i < 250000; i++) { 173 fillNextRandomBuffer(buf, blit_width, blit_height); 174 SDL_LockSurface(sourceSurface); 175 SDL_memcpy(sourceSurface->pixels, buf, blit_width * blit_height * sizeof(Uint32)); 176 SDL_UnlockSurface(sourceSurface); 177 178 SDL_Rect dest_rect; 179 int location = (int)getRandomUint32(); 180 dest_rect.x = location % (width - 15 - 1); 181 dest_rect.y = location % (height - 15 - 1); 182 183 SDL_BlitSurface(sourceSurface, NULL, dest_surface, &dest_rect); 184 } 185 // Check result 186 const Uint32 hash = hashSurfacePixels(dest_surface); 187 // Clean up 188 SDL_DestroySurface(dest_surface); 189 SDLTest_AssertCheck(hash == correct_hash, 190 "Should render identically, expected hash 0x%" SDL_PRIx32 ", got 0x%" SDL_PRIx32, 191 correct_hash, hash); 192 SDL_DestroySurface(sourceSurface); 193 SDL_free(buf); 194 return TEST_COMPLETED; 195} 196 197static const SDLTest_TestCaseReference blitTest1 = { 198 blit_testExampleApplicationRender, "blit_testExampleApplicationRender", 199 "Test example application render.", TEST_ENABLED 200}; 201static const SDLTest_TestCaseReference blitTest2 = { 202 blit_testRandomToRandomSVGA, "blit_testRandomToRandomSVGA", 203 "Test SVGA noise render.", TEST_ENABLED 204}; 205static const SDLTest_TestCaseReference blitTest3 = { 206 blit_testRandomToRandomSVGAMultipleIterations, "blit_testRandomToRandomSVGAMultipleIterations", 207 "Test SVGA noise render (250k iterations).", TEST_ENABLED 208}; 209static const SDLTest_TestCaseReference *blitTests[] = { 210 &blitTest1, &blitTest2, &blitTest3, NULL 211}; 212 213SDLTest_TestSuiteReference blitTestSuite = { 214 "Blending", 215 blitSetUp, 216 blitTests, 217 NULL 218}; 219[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.