Backport FTOC optimization from 5.1

This commit is contained in:
Colby Klein
2017-05-30 03:04:26 -07:00
parent e5e5b94242
commit 1c920a4197
+24 -11
View File
@@ -265,18 +265,31 @@ public:
* incorrect, the first and/or last values may be biased. */
inline unsigned char FTOC(float a)
{
/* lfintf is much faster than C casts. We don't care which way negative values
* are rounded, since we'll clamp them to zero below. Be sure to truncate (not
* round) positive values. The highest value that should be converted to 1 is
* roughly (1/256 - 0.00001); if we don't truncate, values up to (1/256 + 0.5)
* will be converted to 1, which is wrong. */
int ret = lrintf(a*256.f - 0.5f);
//This value is 2^52 * 1.5.
const double INT_MANTISSA = 6755399441055744.0;
/* Benchmarking shows that clamping here, as integers, is much faster than clamping
* before the conversion, as floats. */
if( ret<0 ) return 0;
else if( ret>255 ) return 255;
else return (unsigned char) ret;
/* Be sure to truncate (not round) positive values. The highest value that
* should be converted to 1 is roughly(1 / 256 - 0.00001); if we don't
* truncate, values up to (1/256 + 0.5) will be converted to 1, which is
* wrong. */
double base = double(a * 256.f - 0.5f);
/* INT_MANTISSA is chosen such that, when added to a sufficiently small
* double, the mantissa bits of that double can be reinterpreted as that
* number rounded to an integer. This is done to improve performance. */
base += INT_MANTISSA;
int ret = reinterpret_cast<int&>(base);
/* Benchmarking shows that clamping here, as integers, is much faster than clamping
* before the conversion, as floats. */
if (ret < 0) {
return 0;
}
if (ret > 255) {
return 255;
}
return static_cast<unsigned char>(ret);
}
/* Color type used only in vertex lists. OpenGL expects colors in