18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkRandom_DEFINED 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkRandom_DEFINED 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScalar.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org/** \class SkLCGRandom 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Utility class that implements pseudo random 32bit numbers using a fast 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com linear equation. Unlike rand(), this class holds its own seed (initially 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set to 0), so that multiple instances can be used with no side-effects. 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 19e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgclass SkLCGRandom { 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 21e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org SkLCGRandom() : fSeed(0) {} 22e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org SkLCGRandom(uint32_t seed) : fSeed(seed) {} 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the next pseudo random number as an unsigned 32bit value. 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t nextU() { uint32_t r = fSeed * kMul + kAdd; fSeed = r; return r; } 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the next pseudo random number as a signed 32bit value. 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t nextS() { return (int32_t)this->nextU(); } 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the next pseudo random number as an unsigned 16bit value. 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com U16CPU nextU16() { return this->nextU() >> 16; } 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the next pseudo random number as a signed 16bit value. 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com S16CPU nextS16() { return this->nextS() >> 16; } 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 40223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org /** 41223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org * Returns value [0...1) as a float 42223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org */ 43223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org float nextF() { 44223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org // const is 1 / (2^32 - 1) 45223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org return (float)(this->nextU() * 2.32830644e-10); 46223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org } 47223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org 48223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org /** 49223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org * Returns value [min...max) as a float 50223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org */ 51223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org float nextRangeF(float min, float max) { 52223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org return min + this->nextF() * (max - min); 53223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org } 54223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the next pseudo random number, as an unsigned value of 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at most bitCount bits. 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param bitCount The maximum number of bits to be returned 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t nextBits(unsigned bitCount) { 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(bitCount > 0 && bitCount <= 32); 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->nextU() >> (32 - bitCount); 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the next pseudo random unsigned number, mapped to lie within 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com [min, max] inclusive. 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t nextRangeU(uint32_t min, uint32_t max) { 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(min <= max); 696d5d08f14f1907d516ee28656dfd9ca063e0f7fcbsalomon@google.com uint32_t range = max - min + 1; 706d5d08f14f1907d516ee28656dfd9ca063e0f7fcbsalomon@google.com if (0 == range) { 716d5d08f14f1907d516ee28656dfd9ca063e0f7fcbsalomon@google.com return this->nextU(); 726d5d08f14f1907d516ee28656dfd9ca063e0f7fcbsalomon@google.com } else { 736d5d08f14f1907d516ee28656dfd9ca063e0f7fcbsalomon@google.com return min + this->nextU() % range; 746d5d08f14f1907d516ee28656dfd9ca063e0f7fcbsalomon@google.com } 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 77d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com /** Return the next pseudo random unsigned number, mapped to lie within 78d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com [0, count). 79d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com */ 80d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com uint32_t nextULessThan(uint32_t count) { 81d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com SkASSERT(count > 0); 82d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com return this->nextRangeU(0, count - 1); 83d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com } 84d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the next pseudo random number expressed as an unsigned SkFixed 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com in the range [0..SK_Fixed1). 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFixed nextUFixed1() { return this->nextU() >> 16; } 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the next pseudo random number expressed as a signed SkFixed 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com in the range (-SK_Fixed1..SK_Fixed1). 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFixed nextSFixed1() { return this->nextS() >> 15; } 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the next pseudo random number expressed as a SkScalar 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com in the range [0..SK_Scalar1). 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); } 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the next pseudo random number expressed as a SkScalar 1010a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com in the range [min..max). 1020a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com */ 1030a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com SkScalar nextRangeScalar(SkScalar min, SkScalar max) { 104d173b8760887f9b10cd43cc99ad6b8011e269370mike@reedtribe.org return this->nextUScalar1() * (max - min) + min; 1050a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com } 1060a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com 1070a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com /** Return the next pseudo random number expressed as a SkScalar 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com in the range (-SK_Scalar1..SK_Scalar1). 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); } 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 112d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com /** Return the next pseudo random number as a bool. 113d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com */ 114d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com bool nextBool() { return this->nextU() >= 0x80000000; } 115d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com 116705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com /** A biased version of nextBool(). 117705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com */ 118705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com bool nextBiasedBool(SkScalar fractionTrue) { 119705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com SkASSERT(fractionTrue >= 0 && fractionTrue <= SK_Scalar1); 120705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com return this->nextUScalar1() <= fractionTrue; 121705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com } 122705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com 12357212f9469c8056bab3c85243dbb904e386eab95reed@google.com /** 12457212f9469c8056bab3c85243dbb904e386eab95reed@google.com * Return the next pseudo random number as a signed 64bit value. 12557212f9469c8056bab3c85243dbb904e386eab95reed@google.com */ 12657212f9469c8056bab3c85243dbb904e386eab95reed@google.com int64_t next64() { 12757212f9469c8056bab3c85243dbb904e386eab95reed@google.com int64_t hi = this->nextS(); 12857212f9469c8056bab3c85243dbb904e386eab95reed@google.com return (hi << 32) | this->nextU(); 12957212f9469c8056bab3c85243dbb904e386eab95reed@google.com } 13057212f9469c8056bab3c85243dbb904e386eab95reed@google.com 131425a8c71e43841bf6e8622bf7f6a7985a2efe4c7reed@google.com /** 132425a8c71e43841bf6e8622bf7f6a7985a2efe4c7reed@google.com * Return the current seed. This allows the caller to later reset to the 133425a8c71e43841bf6e8622bf7f6a7985a2efe4c7reed@google.com * same seed (using setSeed) so it can generate the same sequence. 134425a8c71e43841bf6e8622bf7f6a7985a2efe4c7reed@google.com */ 135425a8c71e43841bf6e8622bf7f6a7985a2efe4c7reed@google.com int32_t getSeed() const { return fSeed; } 136425a8c71e43841bf6e8622bf7f6a7985a2efe4c7reed@google.com 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the seed of the random object. The seed is initialized to 0 when the 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com object is first created, and is updated each time the next pseudo random 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com number is requested. 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setSeed(int32_t seed) { fSeed = (uint32_t)seed; } 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // See "Numerical Recipes in C", 1992 page 284 for these constants 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com enum { 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kMul = 1664525, 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kAdd = 1013904223 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t fSeed; 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 152e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org/** \class SkRandom 15324d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 154a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com Utility class that implements pseudo random 32bit numbers using Marsaglia's 15524d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com multiply-with-carry "mother of all" algorithm. Unlike rand(), this class holds 156a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com its own state, so that multiple instances can be used with no side-effects. 15724d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 158a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com Has a large period and all bits are well-randomized. 159a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 160e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgclass SkRandom { 161a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.compublic: 162e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org SkRandom() { init(0); } 163e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org SkRandom(uint32_t seed) { init(seed); } 164e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org SkRandom(const SkRandom& rand) : fK(rand.fK), fJ(rand.fJ) {} 165a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com 166e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org SkRandom& operator=(const SkRandom& rand) { 167a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com fK = rand.fK; 168a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com fJ = rand.fJ; 169a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com 170a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com return *this; 171a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } 17224d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 173a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** Return the next pseudo random number as an unsigned 32bit value. 174a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 175a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com uint32_t nextU() { 176a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com fK = kKMul*(fK & 0xffff) + (fK >> 16); 177a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com fJ = kJMul*(fJ & 0xffff) + (fJ >> 16); 178a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com return (((fK << 16) | (fK >> 16)) + fJ); 179a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } 18024d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 181a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** Return the next pseudo random number as a signed 32bit value. 182a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 183a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com int32_t nextS() { return (int32_t)this->nextU(); } 18424d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 185a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** Return the next pseudo random number as an unsigned 16bit value. 186a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 187a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com U16CPU nextU16() { return this->nextU() >> 16; } 18824d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 189a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** Return the next pseudo random number as a signed 16bit value. 190a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 191a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com S16CPU nextS16() { return this->nextS() >> 16; } 19224d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 193a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** 194a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com * Returns value [0...1) as an IEEE float 195a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 196a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com float nextF() { 197a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com unsigned int floatint = 0x3f800000 | (this->nextU() >> 9); 198753a362cfc336062cae7b55c285332a0d1c8ae72bsalomon@google.com float f = SkBits2Float(floatint) - 1.0f; 199a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com return f; 200a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } 20124d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 202a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** 203a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com * Returns value [min...max) as a float 204a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 205a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com float nextRangeF(float min, float max) { 206a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com return min + this->nextF() * (max - min); 207a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } 20824d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 209a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** Return the next pseudo random number, as an unsigned value of 210a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com at most bitCount bits. 211a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com @param bitCount The maximum number of bits to be returned 212a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 213a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com uint32_t nextBits(unsigned bitCount) { 214a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com SkASSERT(bitCount > 0 && bitCount <= 32); 215a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com return this->nextU() >> (32 - bitCount); 216a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } 21724d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 218a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** Return the next pseudo random unsigned number, mapped to lie within 219a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com [min, max] inclusive. 220a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 221a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com uint32_t nextRangeU(uint32_t min, uint32_t max) { 222a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com SkASSERT(min <= max); 223a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com uint32_t range = max - min + 1; 224a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com if (0 == range) { 225a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com return this->nextU(); 226a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } else { 227a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com return min + this->nextU() % range; 228a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } 229a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } 23024d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 231a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** Return the next pseudo random unsigned number, mapped to lie within 232a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com [0, count). 233a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 234a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com uint32_t nextULessThan(uint32_t count) { 235a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com SkASSERT(count > 0); 236a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com return this->nextRangeU(0, count - 1); 237a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } 23824d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 239a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** Return the next pseudo random number expressed as an unsigned SkFixed 240a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com in the range [0..SK_Fixed1). 241a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 242a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com SkFixed nextUFixed1() { return this->nextU() >> 16; } 24324d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 244a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** Return the next pseudo random number expressed as a signed SkFixed 245a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com in the range (-SK_Fixed1..SK_Fixed1). 246a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 247a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com SkFixed nextSFixed1() { return this->nextS() >> 15; } 24824d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 249a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** Return the next pseudo random number expressed as a SkScalar 250a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com in the range [0..SK_Scalar1). 251a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 252a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); } 25324d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 254a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** Return the next pseudo random number expressed as a SkScalar 255a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com in the range [min..max). 256a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 257a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com SkScalar nextRangeScalar(SkScalar min, SkScalar max) { 258d173b8760887f9b10cd43cc99ad6b8011e269370mike@reedtribe.org return this->nextUScalar1() * (max - min) + min; 259a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } 26024d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 261a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** Return the next pseudo random number expressed as a SkScalar 262a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com in the range (-SK_Scalar1..SK_Scalar1). 263a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 264a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); } 26524d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 266a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** Return the next pseudo random number as a bool. 267a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 268a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com bool nextBool() { return this->nextU() >= 0x80000000; } 26924d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 270a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com /** A biased version of nextBool(). 271a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 272a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com bool nextBiasedBool(SkScalar fractionTrue) { 273a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com SkASSERT(fractionTrue >= 0 && fractionTrue <= SK_Scalar1); 274a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com return this->nextUScalar1() <= fractionTrue; 275a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } 27624d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 27757212f9469c8056bab3c85243dbb904e386eab95reed@google.com /** 27857212f9469c8056bab3c85243dbb904e386eab95reed@google.com * Return the next pseudo random number as a signed 64bit value. 279a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 28057212f9469c8056bab3c85243dbb904e386eab95reed@google.com int64_t next64() { 28157212f9469c8056bab3c85243dbb904e386eab95reed@google.com int64_t hi = this->nextS(); 28257212f9469c8056bab3c85243dbb904e386eab95reed@google.com return (hi << 32) | this->nextU(); 28357212f9469c8056bab3c85243dbb904e386eab95reed@google.com } 284f5e1f63461d0a4dcb4bd5d0388ec6d392b97e5f0skia.committer@gmail.com 28524d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com /** Reset the random object. 286a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com */ 287a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com void setSeed(uint32_t seed) { init(seed); } 288a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com 289a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.comprivate: 290a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com // Initialize state variables with LCG. 29124d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com // We must ensure that both J and K are non-zero, otherwise the 292a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com // multiply-with-carry step will forevermore return zero. 293a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com void init(uint32_t seed) { 294a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com fK = NextLCG(seed); 295a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com if (0 == fK) { 296a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com fK = NextLCG(fK); 297a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } 298a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com fJ = NextLCG(fK); 299a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com if (0 == fJ) { 300a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com fJ = NextLCG(fJ); 301a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } 302a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com SkASSERT(0 != fK && 0 != fJ); 303a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com } 304a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com static uint32_t NextLCG(uint32_t seed) { return kMul*seed + kAdd; } 305a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com 306a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com // See "Numerical Recipes in C", 1992 page 284 for these constants 307a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com // For the LCG that sets the initial state from a seed 308a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com enum { 309a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com kMul = 1664525, 310a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com kAdd = 1013904223 311a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com }; 312a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com // Constants for the multiply-with-carry steps 313a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com enum { 314a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com kKMul = 30345, 315a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com kJMul = 18000, 316a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com }; 31724d5ee4f886dd238731381b92e9d13d7194af728skia.committer@gmail.com 318a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com uint32_t fK; 319a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com uint32_t fJ; 320a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com}; 321a8e66f76d9333939d7cbbc9d99188901fde91291jvanverth@google.com 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 323