1// [Blend2D]
2// 2D Vector Graphics Powered by a JIT Compiler.
3//
4// [License]
5// Zlib - See LICENSE.md file in the package.
6
7#include "./blapi-build_p.h"
8#include "./blrandom_p.h"
9#include "./blsimd_p.h"
10
11// ============================================================================
12// [BLRandom - Core]
13// ============================================================================
14
15void blRandomReset(BLRandom* self, uint64_t seed) noexcept { blRandomResetInline(self, seed); }
16double blRandomNextDouble(BLRandom* self) noexcept { return blRandomNextDoubleInline(self); }
17uint32_t blRandomNextUInt32(BLRandom* self) noexcept { return blRandomNextUInt32Inline(self); }
18uint64_t blRandomNextUInt64(BLRandom* self) noexcept { return blRandomNextUInt64Inline(self); }
19
20// ============================================================================
21// [BLRandom - Unit Tests]
22// ============================================================================
23
24#ifdef BL_TEST
25UNIT(blend2d_random) {
26 // Number of iterations for tests that use loop.
27 enum { kCount = 1000000 };
28
29 // Test whether the SIMD implementation matches the C++ one.
30 #if defined(BL_TARGET_OPT_SSE2)
31 {
32 BLRandom a(0);
33 BLRandom b(0);
34
35 SIMD::I128 bLo = blRandomNextUInt64AsI128Inline(&b);
36 SIMD::I128 bHi = SIMD::vswizi32<2, 3, 0, 1>(bLo);
37
38 uint64_t aVal = a.nextUInt64();
39 uint64_t bVal = (uint64_t(SIMD::vcvti128i32(bLo)) ) +
40 (uint64_t(SIMD::vcvti128i32(bHi)) << 32) ;
41
42 EXPECT(aVal == bVal);
43 }
44 #endif
45
46 // Test whether the random 32-bit integer is the HI part of the 64-bit one.
47 {
48 BLRandom a(0);
49 BLRandom b(0);
50 EXPECT(uint32_t(a.nextUInt64() >> 32) == b.nextUInt32());
51 }
52
53 // Test whether returned doubles satisfy [0..1) condition.
54 {
55 // Supply a low-entropy seed on purpose.
56 BLRandom rnd(3);
57
58 uint32_t below = 0;
59 uint32_t above = 0;
60
61 for (uint32_t i = 0; i < kCount; i++) {
62 double x = rnd.nextDouble();
63 below += x < 0.5;
64 above += x >= 0.5;
65 EXPECT(x >= 0.0 && x < 1.0);
66 }
67 INFO("Random numbers at [0.0, 0.5): %u of %u", below, kCount);
68 INFO("Random numbers at [0.5, 1.0): %u of %u", above, kCount);
69 }
70}
71#endif
72