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 ...@@ -86,10 +86,10 @@ class MultiWindowSample : public SampleApplication
int baseY = rootWindow.osWindow->getY(); int baseY = rootWindow.osWindow->getY();
for (auto &window : mWindows) for (auto &window : mWindows)
{ {
int x = baseX + static_cast<int>(RandomBetween(0, 512)); int x = baseX + mRNG.randomIntBetween(0, 512);
int y = baseY + static_cast<int>(RandomBetween(0, 512)); int y = baseY + mRNG.randomIntBetween(0, 512);
int width = static_cast<int>(RandomBetween(128, 512)); int width = mRNG.randomIntBetween(128, 512);
int height = static_cast<int>(RandomBetween(128, 512)); int height = mRNG.randomIntBetween(128, 512);
window.osWindow->setPosition(x, y); window.osWindow->setPosition(x, y);
window.osWindow->resize(width, height); window.osWindow->resize(width, height);
} }
...@@ -191,6 +191,8 @@ class MultiWindowSample : public SampleApplication ...@@ -191,6 +191,8 @@ class MultiWindowSample : public SampleApplication
EGLSurface surface; EGLSurface surface;
}; };
std::vector<window> mWindows; std::vector<window> mWindows;
RNG mRNG;
}; };
int main(int argc, char **argv) int main(int argc, char **argv)
......
...@@ -98,16 +98,16 @@ class ParticleSystemSample : public SampleApplication ...@@ -98,16 +98,16 @@ class ParticleSystemSample : public SampleApplication
// Fill in particle data array // Fill in particle data array
for (size_t i = 0; i < mParticleCount; i++) 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 endAngle = mRNG.randomFloatBetween(0, 2.0f * float(M_PI));
float endRadius = RandomBetween(0.0f, 2.0f); float endRadius = mRNG.randomFloatBetween(0.0f, 2.0f);
mParticles[i].endPosition.x = sinf(endAngle) * endRadius; mParticles[i].endPosition.x = sinf(endAngle) * endRadius;
mParticles[i].endPosition.y = cosf(endAngle) * endRadius; mParticles[i].endPosition.y = cosf(endAngle) * endRadius;
mParticles[i].endPosition.z = 0.0f; mParticles[i].endPosition.z = 0.0f;
float startAngle = RandomBetween(0, 2.0f * float(M_PI)); float startAngle = mRNG.randomFloatBetween(0, 2.0f * float(M_PI));
float startRadius = RandomBetween(0.0f, 0.25f); float startRadius = mRNG.randomFloatBetween(0.0f, 0.25f);
mParticles[i].startPosition.x = sinf(startAngle) * startRadius; mParticles[i].startPosition.x = sinf(startAngle) * startRadius;
mParticles[i].startPosition.y = cosf(startAngle) * startRadius; mParticles[i].startPosition.y = cosf(startAngle) * startRadius;
mParticles[i].startPosition.z = 0.0f; mParticles[i].startPosition.z = 0.0f;
...@@ -129,12 +129,9 @@ class ParticleSystemSample : public SampleApplication ...@@ -129,12 +129,9 @@ class ParticleSystemSample : public SampleApplication
return true; return true;
} }
virtual void destroy() void destroy() override { glDeleteProgram(mProgram); }
{
glDeleteProgram(mProgram);
}
virtual void step(float dt, double totalTime) void step(float dt, double totalTime) override
{ {
// Use the program object // Use the program object
glUseProgram(mProgram); glUseProgram(mProgram);
...@@ -145,16 +142,14 @@ class ParticleSystemSample : public SampleApplication ...@@ -145,16 +142,14 @@ class ParticleSystemSample : public SampleApplication
mParticleTime = 0.0f; mParticleTime = 0.0f;
// Pick a new start location and color // Pick a new start location and color
Vector3 centerPos(RandomBetween(-0.5f, 0.5f), Vector3 centerPos(mRNG.randomFloatBetween(-0.5f, 0.5f),
RandomBetween(-0.5f, 0.5f), mRNG.randomFloatBetween(-0.5f, 0.5f),
RandomBetween(-0.5f, 0.5f)); mRNG.randomFloatBetween(-0.5f, 0.5f));
glUniform3fv(mCenterPositionLoc, 1, centerPos.data()); glUniform3fv(mCenterPositionLoc, 1, centerPos.data());
// Random color // Random color
Vector4 color(RandomBetween(0.0f, 1.0f), Vector4 color(mRNG.randomFloatBetween(0.0f, 1.0f), mRNG.randomFloatBetween(0.0f, 1.0f),
RandomBetween(0.0f, 1.0f), mRNG.randomFloatBetween(0.0f, 1.0f), 0.5f);
RandomBetween(0.0f, 1.0f),
0.5f);
glUniform4fv(mColorLoc, 1, color.data()); glUniform4fv(mColorLoc, 1, color.data());
} }
...@@ -224,6 +219,7 @@ class ParticleSystemSample : public SampleApplication ...@@ -224,6 +219,7 @@ class ParticleSystemSample : public SampleApplication
static const size_t mParticleCount = 1024; static const size_t mParticleCount = 1024;
std::array<Particle, mParticleCount> mParticles; std::array<Particle, mParticleCount> mParticles;
float mParticleTime; float mParticleTime;
RNG mRNG;
}; };
int main(int argc, char **argv) int main(int argc, char **argv)
......
...@@ -30,8 +30,6 @@ SampleApplication::SampleApplication(const std::string &name, ...@@ -30,8 +30,6 @@ SampleApplication::SampleApplication(const std::string &name,
// Disable vsync // Disable vsync
mEGLWindow->setSwapInterval(0); mEGLWindow->setSwapInterval(0);
angle::RandomInitFromTime();
} }
SampleApplication::~SampleApplication() SampleApplication::~SampleApplication()
......
...@@ -13,7 +13,7 @@ using namespace angle; ...@@ -13,7 +13,7 @@ using namespace angle;
class OcclusionQueriesTest : public ANGLETest class OcclusionQueriesTest : public ANGLETest
{ {
protected: protected:
OcclusionQueriesTest() OcclusionQueriesTest() : mProgram(0), mRNG(1)
{ {
setWindowWidth(128); setWindowWidth(128);
setWindowHeight(128); setWindowHeight(128);
...@@ -22,11 +22,9 @@ class OcclusionQueriesTest : public ANGLETest ...@@ -22,11 +22,9 @@ class OcclusionQueriesTest : public ANGLETest
setConfigBlueBits(8); setConfigBlueBits(8);
setConfigAlphaBits(8); setConfigAlphaBits(8);
setConfigDepthBits(24); setConfigDepthBits(24);
mProgram = 0;
} }
virtual void SetUp() void SetUp() override
{ {
ANGLETest::SetUp(); ANGLETest::SetUp();
...@@ -49,13 +47,10 @@ class OcclusionQueriesTest : public ANGLETest ...@@ -49,13 +47,10 @@ class OcclusionQueriesTest : public ANGLETest
); );
mProgram = CompileProgram(passthroughVS, passthroughPS); mProgram = CompileProgram(passthroughVS, passthroughPS);
if (mProgram == 0) ASSERT_NE(0u, mProgram);
{
FAIL() << "shader compilation failed.";
}
} }
virtual void TearDown() void TearDown() override
{ {
glDeleteProgram(mProgram); glDeleteProgram(mProgram);
...@@ -63,6 +58,7 @@ class OcclusionQueriesTest : public ANGLETest ...@@ -63,6 +58,7 @@ class OcclusionQueriesTest : public ANGLETest
} }
GLuint mProgram; GLuint mProgram;
RNG mRNG;
}; };
TEST_P(OcclusionQueriesTest, IsOccluded) TEST_P(OcclusionQueriesTest, IsOccluded)
...@@ -328,8 +324,8 @@ TEST_P(OcclusionQueriesTest, MultiContext) ...@@ -328,8 +324,8 @@ TEST_P(OcclusionQueriesTest, MultiContext)
{ {
eglMakeCurrent(display, surface, surface, context.context); eglMakeCurrent(display, surface, surface, context.context);
float depth = float depth = context.visiblePasses[pass] ? mRNG.randomFloatBetween(0.0f, 0.4f)
context.visiblePasses[pass] ? RandomBetween(0.0f, 0.4f) : RandomBetween(0.6f, 1.0f); : mRNG.randomFloatBetween(0.6f, 1.0f);
drawQuad(context.program, "position", depth); drawQuad(context.program, "position", depth);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
......
...@@ -35,6 +35,12 @@ size_t VectorSizeBytes(const std::vector<T> &vec) ...@@ -35,6 +35,12 @@ size_t VectorSizeBytes(const std::vector<T> &vec)
return sizeof(T) * vec.size(); return sizeof(T) * vec.size();
} }
Vector3 RandomVector3(RNG *rng)
{
return Vector3(rng->randomNegativeOneToOne(), rng->randomNegativeOneToOne(),
rng->randomNegativeOneToOne());
}
struct InstancingPerfParams final : public RenderTestParams struct InstancingPerfParams final : public RenderTestParams
{ {
// Common default options // Common default options
...@@ -93,6 +99,7 @@ class InstancingPerfBenchmark : public ANGLERenderTest, ...@@ -93,6 +99,7 @@ class InstancingPerfBenchmark : public ANGLERenderTest,
std::vector<Vector3> mTranslateData; std::vector<Vector3> mTranslateData;
std::vector<float> mSizeData; std::vector<float> mSizeData;
std::vector<Vector3> mColorData; std::vector<Vector3> mColorData;
angle::RNG mRNG;
}; };
InstancingPerfBenchmark::InstancingPerfBenchmark() InstancingPerfBenchmark::InstancingPerfBenchmark()
...@@ -155,8 +162,7 @@ void InstancingPerfBenchmark::initializeBenchmark() ...@@ -155,8 +162,7 @@ void InstancingPerfBenchmark::initializeBenchmark()
indexData.push_back(baseIndexData[indexIndex] + pointIndex * pointVertexStride); indexData.push_back(baseIndexData[indexIndex] + pointIndex * pointVertexStride);
} }
Vector3 randVec(RandomNegativeOneToOne(), RandomNegativeOneToOne(), Vector3 randVec = RandomVector3(&mRNG);
RandomNegativeOneToOne());
for (GLuint vertexIndex = 0; vertexIndex < 4; ++vertexIndex) for (GLuint vertexIndex = 0; vertexIndex < 4; ++vertexIndex)
{ {
positionData.push_back(basePositionData[vertexIndex]); positionData.push_back(basePositionData[vertexIndex]);
...@@ -181,8 +187,7 @@ void InstancingPerfBenchmark::initializeBenchmark() ...@@ -181,8 +187,7 @@ void InstancingPerfBenchmark::initializeBenchmark()
for (GLuint pointIndex = 0; pointIndex < mNumPoints; ++pointIndex) for (GLuint pointIndex = 0; pointIndex < mNumPoints; ++pointIndex)
{ {
Vector3 randVec(RandomNegativeOneToOne(), RandomNegativeOneToOne(), Vector3 randVec = RandomVector3(&mRNG);
RandomNegativeOneToOne());
mTranslateData.push_back(randVec); mTranslateData.push_back(randVec);
} }
......
...@@ -64,6 +64,7 @@ class PointSpritesBenchmark : public ANGLERenderTest, ...@@ -64,6 +64,7 @@ class PointSpritesBenchmark : public ANGLERenderTest,
private: private:
GLuint mProgram; GLuint mProgram;
GLuint mBuffer; GLuint mBuffer;
RNG mRNG;
}; };
std::string PointSpritesParams::suffix() const std::string PointSpritesParams::suffix() const
...@@ -78,7 +79,7 @@ std::string PointSpritesParams::suffix() const ...@@ -78,7 +79,7 @@ std::string PointSpritesParams::suffix() const
} }
PointSpritesBenchmark::PointSpritesBenchmark() PointSpritesBenchmark::PointSpritesBenchmark()
: ANGLERenderTest("PointSprites", GetParam()) : ANGLERenderTest("PointSprites", GetParam()), mRNG(1)
{ {
} }
...@@ -152,7 +153,7 @@ void PointSpritesBenchmark::initializeBenchmark() ...@@ -152,7 +153,7 @@ void PointSpritesBenchmark::initializeBenchmark()
std::vector<float> vertexPositions(params.count * 2); std::vector<float> vertexPositions(params.count * 2);
for (size_t pointIndex = 0; pointIndex < vertexPositions.size(); ++pointIndex) for (size_t pointIndex = 0; pointIndex < vertexPositions.size(); ++pointIndex)
{ {
vertexPositions[pointIndex] = RandomBetween(-1.0f, 1.0f); vertexPositions[pointIndex] = mRNG.randomNegativeOneToOne();
} }
glGenBuffers(1, &mBuffer); glGenBuffers(1, &mBuffer);
......
...@@ -8,30 +8,68 @@ ...@@ -8,30 +8,68 @@
// //
#include "random_utils.h" #include "random_utils.h"
#include <time.h>
#include <chrono>
#include <cstdlib> #include <cstdlib>
namespace angle 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 } // namespace angle
...@@ -10,14 +10,33 @@ ...@@ -10,14 +10,33 @@
#ifndef UTIL_RANDOM_UTILS_H #ifndef UTIL_RANDOM_UTILS_H
#define UTIL_RANDOM_UTILS_H #define UTIL_RANDOM_UTILS_H
// TODO(jmadill): Rework this if Chromium decides to ban <random>
#include <random>
namespace angle namespace angle
{ {
// TODO(jmadill): Should make this a class class RNG
void RandomInitFromTime(); {
float RandomFloat(); public:
float RandomBetween(float min, float max); // Seed from clock
float RandomNegativeOneToOne(); 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 } // 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