1
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#ifndef SkRandom_DEFINED
11#define SkRandom_DEFINED
12
13#include "Sk64.h"
14#include "SkScalar.h"
15
16/** \class SkRandom
17
18    Utility class that implements pseudo random 32bit numbers using a fast
19    linear equation. Unlike rand(), this class holds its own seed (initially
20    set to 0), so that multiple instances can be used with no side-effects.
21*/
22class SkRandom {
23public:
24    SkRandom() : fSeed(0) {}
25    SkRandom(uint32_t seed) : fSeed(seed) {}
26
27    /** Return the next pseudo random number as an unsigned 32bit value.
28    */
29    uint32_t nextU() { uint32_t r = fSeed * kMul + kAdd; fSeed = r; return r; }
30
31    /** Return the next pseudo random number as a signed 32bit value.
32    */
33    int32_t nextS() { return (int32_t)this->nextU(); }
34
35    /** Return the next pseudo random number as an unsigned 16bit value.
36    */
37    U16CPU nextU16() { return this->nextU() >> 16; }
38
39    /** Return the next pseudo random number as a signed 16bit value.
40    */
41    S16CPU nextS16() { return this->nextS() >> 16; }
42
43    /** Return the next pseudo random number, as an unsigned value of
44        at most bitCount bits.
45        @param bitCount The maximum number of bits to be returned
46    */
47    uint32_t nextBits(unsigned bitCount) {
48        SkASSERT(bitCount > 0 && bitCount <= 32);
49        return this->nextU() >> (32 - bitCount);
50    }
51
52    /** Return the next pseudo random unsigned number, mapped to lie within
53        [min, max] inclusive.
54    */
55    uint32_t nextRangeU(uint32_t min, uint32_t max) {
56        SkASSERT(min <= max);
57        return min + this->nextU() % (max - min + 1);
58    }
59
60    /** Return the next pseudo random number expressed as an unsigned SkFixed
61        in the range [0..SK_Fixed1).
62    */
63    SkFixed nextUFixed1() { return this->nextU() >> 16; }
64
65    /** Return the next pseudo random number expressed as a signed SkFixed
66        in the range (-SK_Fixed1..SK_Fixed1).
67    */
68    SkFixed nextSFixed1() { return this->nextS() >> 15; }
69
70    /** Return the next pseudo random number expressed as a SkScalar
71        in the range [0..SK_Scalar1).
72    */
73    SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); }
74
75    /** Return the next pseudo random number expressed as a SkScalar
76        in the range (-SK_Scalar1..SK_Scalar1).
77    */
78    SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }
79
80    /** Return the next pseudo random number as a signed 64bit value.
81    */
82    void next64(Sk64* a) {
83        SkASSERT(a);
84        a->set(this->nextS(), this->nextU());
85    }
86
87    /** Set the seed of the random object. The seed is initialized to 0 when the
88        object is first created, and is updated each time the next pseudo random
89        number is requested.
90    */
91    void setSeed(int32_t seed) { fSeed = (uint32_t)seed; }
92
93private:
94    //  See "Numerical Recipes in C", 1992 page 284 for these constants
95    enum {
96        kMul = 1664525,
97        kAdd = 1013904223
98    };
99    uint32_t fSeed;
100};
101
102#endif
103
104