Commit f83cbc65 by Jamie Madill

Use std::random functions for test and samples RNG.

These standard functions are much more powerful than the C random() routines. Use them to improve the random utils, and use a class to clean things up further. This fixes a problem I was having using random_utils where I was having trouble generating random 32 bit unsigned integers. BUG=angleproject:1290 Change-Id: I5081764053d0667a4e323553b7dea531256aa778 Reviewed-on: https://chromium-review.googlesource.com/323440Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tryjob-Request: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 436e32ae
......@@ -86,10 +86,10 @@ class MultiWindowSample : public SampleApplication
int baseY = rootWindow.osWindow->getY();
for (auto &window : mWindows)
{
int x = baseX + static_cast<int>(RandomBetween(0, 512));
int y = baseY + static_cast<int>(RandomBetween(0, 512));
int width = static_cast<int>(RandomBetween(128, 512));
int height = static_cast<int>(RandomBetween(128, 512));
int x = baseX + mRNG.randomIntBetween(0, 512);
int y = baseY + mRNG.randomIntBetween(0, 512);
int width = mRNG.randomIntBetween(128, 512);
int height = mRNG.randomIntBetween(128, 512);
window.osWindow->setPosition(x, y);
window.osWindow->resize(width, height);
}
......@@ -191,6 +191,8 @@ class MultiWindowSample : public SampleApplication
EGLSurface surface;
};
std::vector<window> mWindows;
RNG mRNG;
};
int main(int argc, char **argv)
......
......@@ -98,16 +98,16 @@ class ParticleSystemSample : public SampleApplication
// Fill in particle data array
for (size_t i = 0; i < mParticleCount; i++)
{
mParticles[i].lifetime = RandomBetween(0.0f, 1.0f);
mParticles[i].lifetime = mRNG.randomFloatBetween(0.0f, 1.0f);
float endAngle = RandomBetween(0, 2.0f * float(M_PI));
float endRadius = RandomBetween(0.0f, 2.0f);
float endAngle = mRNG.randomFloatBetween(0, 2.0f * float(M_PI));
float endRadius = mRNG.randomFloatBetween(0.0f, 2.0f);
mParticles[i].endPosition.x = sinf(endAngle) * endRadius;
mParticles[i].endPosition.y = cosf(endAngle) * endRadius;
mParticles[i].endPosition.z = 0.0f;
float startAngle = RandomBetween(0, 2.0f * float(M_PI));
float startRadius = RandomBetween(0.0f, 0.25f);
float startAngle = mRNG.randomFloatBetween(0, 2.0f * float(M_PI));
float startRadius = mRNG.randomFloatBetween(0.0f, 0.25f);
mParticles[i].startPosition.x = sinf(startAngle) * startRadius;
mParticles[i].startPosition.y = cosf(startAngle) * startRadius;
mParticles[i].startPosition.z = 0.0f;
......@@ -129,12 +129,9 @@ class ParticleSystemSample : public SampleApplication
return true;
}
virtual void destroy()
{
glDeleteProgram(mProgram);
}
void destroy() override { glDeleteProgram(mProgram); }
virtual void step(float dt, double totalTime)
void step(float dt, double totalTime) override
{
// Use the program object
glUseProgram(mProgram);
......@@ -145,16 +142,14 @@ class ParticleSystemSample : public SampleApplication
mParticleTime = 0.0f;
// Pick a new start location and color
Vector3 centerPos(RandomBetween(-0.5f, 0.5f),
RandomBetween(-0.5f, 0.5f),
RandomBetween(-0.5f, 0.5f));
Vector3 centerPos(mRNG.randomFloatBetween(-0.5f, 0.5f),
mRNG.randomFloatBetween(-0.5f, 0.5f),
mRNG.randomFloatBetween(-0.5f, 0.5f));
glUniform3fv(mCenterPositionLoc, 1, centerPos.data());
// Random color
Vector4 color(RandomBetween(0.0f, 1.0f),
RandomBetween(0.0f, 1.0f),
RandomBetween(0.0f, 1.0f),
0.5f);
Vector4 color(mRNG.randomFloatBetween(0.0f, 1.0f), mRNG.randomFloatBetween(0.0f, 1.0f),
mRNG.randomFloatBetween(0.0f, 1.0f), 0.5f);
glUniform4fv(mColorLoc, 1, color.data());
}
......@@ -224,6 +219,7 @@ class ParticleSystemSample : public SampleApplication
static const size_t mParticleCount = 1024;
std::array<Particle, mParticleCount> mParticles;
float mParticleTime;
RNG mRNG;
};
int main(int argc, char **argv)
......
......@@ -30,8 +30,6 @@ SampleApplication::SampleApplication(const std::string &name,
// Disable vsync
mEGLWindow->setSwapInterval(0);
angle::RandomInitFromTime();
}
SampleApplication::~SampleApplication()
......
......@@ -13,7 +13,7 @@ using namespace angle;
class OcclusionQueriesTest : public ANGLETest
{
protected:
OcclusionQueriesTest()
OcclusionQueriesTest() : mProgram(0), mRNG(1)
{
setWindowWidth(128);
setWindowHeight(128);
......@@ -22,11 +22,9 @@ class OcclusionQueriesTest : public ANGLETest
setConfigBlueBits(8);
setConfigAlphaBits(8);
setConfigDepthBits(24);
mProgram = 0;
}
virtual void SetUp()
void SetUp() override
{
ANGLETest::SetUp();
......@@ -49,13 +47,10 @@ class OcclusionQueriesTest : public ANGLETest
);
mProgram = CompileProgram(passthroughVS, passthroughPS);
if (mProgram == 0)
{
FAIL() << "shader compilation failed.";
}
ASSERT_NE(0u, mProgram);
}
virtual void TearDown()
void TearDown() override
{
glDeleteProgram(mProgram);
......@@ -63,6 +58,7 @@ class OcclusionQueriesTest : public ANGLETest
}
GLuint mProgram;
RNG mRNG;
};
TEST_P(OcclusionQueriesTest, IsOccluded)
......@@ -328,8 +324,8 @@ TEST_P(OcclusionQueriesTest, MultiContext)
{
eglMakeCurrent(display, surface, surface, context.context);
float depth =
context.visiblePasses[pass] ? RandomBetween(0.0f, 0.4f) : RandomBetween(0.6f, 1.0f);
float depth = context.visiblePasses[pass] ? mRNG.randomFloatBetween(0.0f, 0.4f)
: mRNG.randomFloatBetween(0.6f, 1.0f);
drawQuad(context.program, "position", depth);
EXPECT_GL_NO_ERROR();
......
......@@ -35,6 +35,12 @@ size_t VectorSizeBytes(const std::vector<T> &vec)
return sizeof(T) * vec.size();
}
Vector3 RandomVector3(RNG *rng)
{
return Vector3(rng->randomNegativeOneToOne(), rng->randomNegativeOneToOne(),
rng->randomNegativeOneToOne());
}
struct InstancingPerfParams final : public RenderTestParams
{
// Common default options
......@@ -93,6 +99,7 @@ class InstancingPerfBenchmark : public ANGLERenderTest,
std::vector<Vector3> mTranslateData;
std::vector<float> mSizeData;
std::vector<Vector3> mColorData;
angle::RNG mRNG;
};
InstancingPerfBenchmark::InstancingPerfBenchmark()
......@@ -155,8 +162,7 @@ void InstancingPerfBenchmark::initializeBenchmark()
indexData.push_back(baseIndexData[indexIndex] + pointIndex * pointVertexStride);
}
Vector3 randVec(RandomNegativeOneToOne(), RandomNegativeOneToOne(),
RandomNegativeOneToOne());
Vector3 randVec = RandomVector3(&mRNG);
for (GLuint vertexIndex = 0; vertexIndex < 4; ++vertexIndex)
{
positionData.push_back(basePositionData[vertexIndex]);
......@@ -181,8 +187,7 @@ void InstancingPerfBenchmark::initializeBenchmark()
for (GLuint pointIndex = 0; pointIndex < mNumPoints; ++pointIndex)
{
Vector3 randVec(RandomNegativeOneToOne(), RandomNegativeOneToOne(),
RandomNegativeOneToOne());
Vector3 randVec = RandomVector3(&mRNG);
mTranslateData.push_back(randVec);
}
......
......@@ -64,6 +64,7 @@ class PointSpritesBenchmark : public ANGLERenderTest,
private:
GLuint mProgram;
GLuint mBuffer;
RNG mRNG;
};
std::string PointSpritesParams::suffix() const
......@@ -78,7 +79,7 @@ std::string PointSpritesParams::suffix() const
}
PointSpritesBenchmark::PointSpritesBenchmark()
: ANGLERenderTest("PointSprites", GetParam())
: ANGLERenderTest("PointSprites", GetParam()), mRNG(1)
{
}
......@@ -152,7 +153,7 @@ void PointSpritesBenchmark::initializeBenchmark()
std::vector<float> vertexPositions(params.count * 2);
for (size_t pointIndex = 0; pointIndex < vertexPositions.size(); ++pointIndex)
{
vertexPositions[pointIndex] = RandomBetween(-1.0f, 1.0f);
vertexPositions[pointIndex] = mRNG.randomNegativeOneToOne();
}
glGenBuffers(1, &mBuffer);
......
......@@ -8,30 +8,68 @@
//
#include "random_utils.h"
#include <time.h>
#include <chrono>
#include <cstdlib>
namespace angle
{
void RandomInitFromTime()
// Seed from clock
RNG::RNG()
{
long long timeSeed = std::chrono::system_clock::now().time_since_epoch().count();
mGenerator.seed(static_cast<unsigned int>(timeSeed));
}
// Seed from fixed number.
RNG::RNG(unsigned int seed) : mGenerator(seed)
{
}
RNG::~RNG()
{
}
void RNG::reseed(unsigned int newSeed)
{
mGenerator.seed(newSeed);
}
int RNG::randomInt()
{
std::uniform_int_distribution<int> intDistribution;
return intDistribution(mGenerator);
}
int RNG::randomIntBetween(int min, int max)
{
std::uniform_int_distribution<int> intDistribution(min, max);
return intDistribution(mGenerator);
}
unsigned int RNG::randomUInt()
{
srand(static_cast<unsigned int>(time(NULL)));
std::uniform_int_distribution<unsigned int> uintDistribution;
return uintDistribution(mGenerator);
}
float RandomFloat()
float RNG::randomFloat()
{
return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
std::uniform_real_distribution<float> floatDistribution;
return floatDistribution(mGenerator);
}
float RandomBetween(float min, float max)
float RNG::randomFloatBetween(float min, float max)
{
return min + RandomFloat() * (max - min);
std::uniform_real_distribution<float> floatDistribution(min, max);
return floatDistribution(mGenerator);
}
float RandomNegativeOneToOne()
float RNG::randomNegativeOneToOne()
{
return RandomBetween(0.0f, 1.0f);
return randomFloatBetween(-1.0f, 1.0f);
}
} // namespace angle
......@@ -10,14 +10,33 @@
#ifndef UTIL_RANDOM_UTILS_H
#define UTIL_RANDOM_UTILS_H
// TODO(jmadill): Rework this if Chromium decides to ban <random>
#include <random>
namespace angle
{
// TODO(jmadill): Should make this a class
void RandomInitFromTime();
float RandomFloat();
float RandomBetween(float min, float max);
float RandomNegativeOneToOne();
class RNG
{
public:
// Seed from clock
RNG();
// Seed from fixed number.
RNG(unsigned int seed);
~RNG();
void reseed(unsigned int newSeed);
int randomInt();
int randomIntBetween(int min, int max);
unsigned int randomUInt();
float randomFloat();
float randomFloatBetween(float min, float max);
float randomNegativeOneToOne();
private:
std::default_random_engine mGenerator;
};
} // namespace angle
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment