summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/CMakeLists.txt2
-rw-r--r--indra/llcommon/llfasttimer.cpp6
-rw-r--r--indra/llcommon/llleap.cpp2
-rw-r--r--indra/llcommon/llprocessor.cpp2
-rw-r--r--indra/llcommon/llprocessor.h2
-rw-r--r--indra/llcommon/lltimer.cpp14
-rw-r--r--indra/llcommon/lltimer.h16
-rw-r--r--indra/llcommon/lltrace.h7
-rw-r--r--indra/llcommon/lltracerecording.h2
-rw-r--r--indra/llcommon/llunit.h193
-rw-r--r--indra/llcommon/tests/llunits_test.cpp (renamed from indra/llcommon/tests/llunit_test.cpp)54
-rw-r--r--indra/newview/llfasttimerview.cpp30
-rw-r--r--indra/newview/pipeline.cpp2
13 files changed, 237 insertions, 95 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index e1f2eb44fd..5b76703af7 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -342,7 +342,7 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
- LL_ADD_INTEGRATION_TEST(llunit "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(reflection "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index cf7655acf7..37e0fbac0a 100644
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -166,7 +166,7 @@ U64 TimeBlock::countsPerSecond() // counts per second for the *64-bit* timer
firstcall = false;
}
#endif
- return sCPUClockFrequency;
+ return sCPUClockFrequency.value();
}
#endif
@@ -408,7 +408,7 @@ void TimeBlock::nextFrame()
}
call_count++;
- LLUnit<LLUnits::Seconds, F64> total_time = 0;
+ LLUnit<LLUnits::Seconds, F64> total_time(0);
LLSD sd;
{
@@ -479,7 +479,7 @@ void TimeBlock::dumpCurTimes()
}
out_str << timerp->getName() << " "
- << std::setprecision(3) << total_time_ms.as<LLUnits::Milliseconds, F32>() << " ms, "
+ << std::setprecision(3) << total_time_ms.as<LLUnits::Milliseconds, F32>().value() << " ms, "
<< num_calls << " calls";
llinfos << out_str.str() << llendl;
diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp
index 0a57ef1c48..84d2a12f65 100644
--- a/indra/llcommon/llleap.cpp
+++ b/indra/llcommon/llleap.cpp
@@ -394,7 +394,7 @@ public:
LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN));
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
LLSD nop;
- F64 until(LLTimer::getElapsedSeconds() + 2);
+ F64 until = (LLTimer::getElapsedSeconds() + 2).value();
while (childin.size() && LLTimer::getElapsedSeconds() < until)
{
mainloop.post(nop);
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 6fe53396ca..5ddfa6fcef 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -875,7 +875,7 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL)
LLProcessorInfo::~LLProcessorInfo() {}
-LLUnit<LLUnits::Megahertz, F64> LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
+LLUnitImplicit<LLUnits::Megahertz, F64> LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); }
bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); }
bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); }
diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h
index 2a21a5c115..fbd427f484 100644
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
@@ -37,7 +37,7 @@ public:
LLProcessorInfo();
~LLProcessorInfo();
- LLUnit<LLUnits::Megahertz, F64> getCPUFrequency() const;
+ LLUnitImplicit<LLUnits::Megahertz, F64> getCPUFrequency() const;
bool hasSSE() const;
bool hasSSE2() const;
bool hasAltivec() const;
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 26063beff0..838155d54d 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -285,14 +285,14 @@ LLTimer::~LLTimer()
}
// static
-LLUnit<LLUnits::Microseconds, U64> LLTimer::getTotalTime()
+LLUnitImplicit<LLUnits::Microseconds, U64> LLTimer::getTotalTime()
{
// simply call into the implementation function.
return totalTime();
}
// static
-LLUnit<LLUnits::Seconds, F64> LLTimer::getTotalSeconds()
+LLUnitImplicit<LLUnits::Seconds, F64> LLTimer::getTotalSeconds()
{
return U64_to_F64(getTotalTime()) * USEC_TO_SEC_F64;
}
@@ -341,23 +341,23 @@ U64 getElapsedTimeAndUpdate(U64& lastClockCount)
}
-LLUnit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeF64() const
+LLUnitImplicit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeF64() const
{
U64 last = mLastClockCount;
return (F64)getElapsedTimeAndUpdate(last) * gClockFrequencyInv;
}
-LLUnit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeF32() const
+LLUnitImplicit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeF32() const
{
return (F32)getElapsedTimeF64();
}
-LLUnit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeAndResetF64()
+LLUnitImplicit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeAndResetF64()
{
return (F64)getElapsedTimeAndUpdate(mLastClockCount) * gClockFrequencyInv;
}
-LLUnit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeAndResetF32()
+LLUnitImplicit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeAndResetF32()
{
return (F32)getElapsedTimeAndResetF64();
}
@@ -370,7 +370,7 @@ void LLTimer::setTimerExpirySec(F32 expiration)
+ (U64)((F32)(expiration * gClockFrequency));
}
-LLUnit<LLUnits::Seconds, F32> LLTimer::getRemainingTimeF32() const
+LLUnitImplicit<LLUnits::Seconds, F32> LLTimer::getRemainingTimeF32() const
{
U64 cur_ticks = get_clock_count();
if (cur_ticks > mExpirationTicks)
diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h
index 5cb2b18111..0ba87d1e15 100644
--- a/indra/llcommon/lltimer.h
+++ b/indra/llcommon/lltimer.h
@@ -67,16 +67,16 @@ public:
// Return a high precision number of seconds since the start of
// this application instance.
- static LLUnit<LLUnits::Seconds, F64> getElapsedSeconds()
+ static LLUnitImplicit<LLUnits::Seconds, F64> getElapsedSeconds()
{
return sTimer->getElapsedTimeF64();
}
// Return a high precision usec since epoch
- static LLUnit<LLUnits::Microseconds, U64> getTotalTime();
+ static LLUnitImplicit<LLUnits::Microseconds, U64> getTotalTime();
// Return a high precision seconds since epoch
- static LLUnit<LLUnits::Seconds, F64> getTotalSeconds();
+ static LLUnitImplicit<LLUnits::Seconds, F64> getTotalSeconds();
// MANIPULATORS
@@ -87,16 +87,16 @@ public:
void setTimerExpirySec(F32 expiration);
BOOL checkExpirationAndReset(F32 expiration);
BOOL hasExpired() const;
- LLUnit<LLUnits::Seconds, F32> getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset
- LLUnit<LLUnits::Seconds, F64> getElapsedTimeAndResetF64();
+ LLUnitImplicit<LLUnits::Seconds, F32> getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset
+ LLUnitImplicit<LLUnits::Seconds, F64> getElapsedTimeAndResetF64();
- LLUnit<LLUnits::Seconds, F32> getRemainingTimeF32() const;
+ LLUnitImplicit<LLUnits::Seconds, F32> getRemainingTimeF32() const;
static BOOL knownBadTimer();
// ACCESSORS
- LLUnit<LLUnits::Seconds, F32> getElapsedTimeF32() const; // Returns elapsed time in seconds
- LLUnit<LLUnits::Seconds, F64> getElapsedTimeF64() const; // Returns elapsed time in seconds
+ LLUnitImplicit<LLUnits::Seconds, F32> getElapsedTimeF32() const; // Returns elapsed time in seconds
+ LLUnitImplicit<LLUnits::Seconds, F64> getElapsedTimeF64() const; // Returns elapsed time in seconds
bool getStarted() const { return mStarted; }
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 6e6bb51e47..25d95d9670 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -435,6 +435,9 @@ namespace LLTrace
class TraceType<TimeBlockAccumulator::CallCountAspect>
: public TraceType<TimeBlockAccumulator>
{
+ public:
+ typedef F32 mean_t;
+
TraceType(const char* name, const char* description = "")
: TraceType<TimeBlockAccumulator>(name, description)
{}
@@ -465,7 +468,7 @@ namespace LLTrace
void sample(UNIT_T value)
{
T converted_value(value);
- getPrimaryAccumulator().sample((storage_t)converted_value);
+ getPrimaryAccumulator().sample(LLUnits::rawValue(converted_value));
}
};
@@ -484,7 +487,7 @@ namespace LLTrace
void add(UNIT_T value)
{
T converted_value(value);
- getPrimaryAccumulator().add((storage_t)converted_value);
+ getPrimaryAccumulator().add(LLUnits::rawValue(converted_value));
}
};
}
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index 6fd1a105d3..f92281cea8 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -205,7 +205,7 @@ namespace LLTrace
U32 getSampleCount(const TraceType<MeasurementAccumulator<F64> >& stat) const;
U32 getSampleCount(const TraceType<MeasurementAccumulator<S64> >& stat) const;
- LLUnit<LLUnits::Seconds, F64> getDuration() const { return mElapsedSeconds; }
+ LLUnit<LLUnits::Seconds, F64> getDuration() const { return LLUnit<LLUnits::Seconds, F64>(mElapsedSeconds); }
private:
friend class ThreadRecorder;
diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h
index 1f3ed0237c..6b023f8287 100644
--- a/indra/llcommon/llunit.h
+++ b/indra/llcommon/llunit.h
@@ -65,6 +65,7 @@ struct ConversionFactor<BASE_UNITS_TAG, BASE_UNITS_TAG, VALUE_TYPE>
return 1;
}
};
+
}
template<typename UNIT_TYPE, typename STORAGE_TYPE>
@@ -73,25 +74,25 @@ struct LLUnit
typedef LLUnit<UNIT_TYPE, STORAGE_TYPE> self_t;
typedef STORAGE_TYPE storage_t;
+ // value initialization
LLUnit(storage_t value = storage_t())
: mValue(value)
{}
+ // unit initialization and conversion
template<typename OTHER_UNIT, typename OTHER_STORAGE>
LLUnit(LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
: mValue(convert(other))
{}
-
- LLUnit(self_t& other)
- : mValue(other.mValue)
- {}
-
+
+ // value assignment
self_t& operator = (storage_t value)
{
mValue = value;
return *this;
}
+ // unit assignment
template<typename OTHER_UNIT, typename OTHER_STORAGE>
self_t& operator = (LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
{
@@ -99,11 +100,6 @@ struct LLUnit
return *this;
}
- operator storage_t() const
- {
- return value();
- }
-
storage_t value() const
{
return mValue;
@@ -157,7 +153,7 @@ struct LLUnit
void operator /= (LLUnit<OTHER_UNIT, OTHER_STORAGE> divisor)
{
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
- llstatic_assert(sizeof(OTHER_UNIT) == 0, "Division of unit types not supported.");
+ llstatic_assert(sizeof(OTHER_UNIT) == 0, "Illegal in-place division of unit types.");
}
template<typename SOURCE_UNITS, typename SOURCE_STORAGE>
@@ -169,34 +165,30 @@ struct LLUnit
}
protected:
-
storage_t mValue;
};
template<typename UNIT_TYPE, typename STORAGE_TYPE>
-struct LLUnitStrict : public LLUnit<UNIT_TYPE, STORAGE_TYPE>
+struct LLUnitImplicit : public LLUnit<UNIT_TYPE, STORAGE_TYPE>
{
- typedef LLUnitStrict<UNIT_TYPE, STORAGE_TYPE> self_t;
+ typedef LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> self_t;
typedef typename LLUnit<UNIT_TYPE, STORAGE_TYPE>::storage_t storage_t;
+ typedef LLUnit<UNIT_TYPE, STORAGE_TYPE> base_t;
- explicit LLUnitStrict(storage_t value = storage_t())
- : LLUnit<UNIT_TYPE, STORAGE_TYPE>(value)
+ LLUnitImplicit(storage_t value = storage_t())
+ : base_t(value)
{}
template<typename OTHER_UNIT, typename OTHER_STORAGE>
- LLUnitStrict(LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
- : LLUnit<UNIT_TYPE, STORAGE_TYPE>(convert(other))
+ LLUnitImplicit(LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
+ : base_t(convert(other))
{}
- LLUnitStrict(self_t& other)
- : LLUnit<UNIT_TYPE, STORAGE_TYPE>(other)
- {}
-
-
-private:
+ // unlike LLUnit, LLUnitImplicit is *implicitly* convertable to a POD scalar (F32, S32, etc)
+ // this allows for interoperability with legacy code
operator storage_t() const
{
- return LLUnit<UNIT_TYPE, STORAGE_TYPE>::value();
+ return value();
}
};
@@ -204,7 +196,7 @@ private:
// operator +
//
template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
-LLUnit<STORAGE_TYPE1, UNIT_TYPE1> operator + (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second)
+LLUnit<UNIT_TYPE1, STORAGE_TYPE1> operator + (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second)
{
LLUnit<UNIT_TYPE1, STORAGE_TYPE1> result(first);
result += second;
@@ -227,6 +219,30 @@ LLUnit<UNIT_TYPE, STORAGE_TYPE> operator + (SCALAR_TYPE first, LLUnit<UNIT_TYPE,
return result;
}
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
+LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator + (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second)
+{
+ LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> result(first);
+ result += second;
+ return result;
+}
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator + (LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second)
+{
+ LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> result(first);
+ result += second;
+ return result;
+}
+
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
+LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator + (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2> second)
+{
+ LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> result(first);
+ result += second;
+ return result;
+}
+
//
// operator -
//
@@ -238,7 +254,6 @@ LLUnit<UNIT_TYPE1, STORAGE_TYPE1> operator - (LLUnit<UNIT_TYPE1, STORAGE_TYPE1>
return result;
}
-
template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
LLUnit<UNIT_TYPE, STORAGE_TYPE> operator - (LLUnit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second)
{
@@ -255,6 +270,30 @@ LLUnit<UNIT_TYPE, STORAGE_TYPE> operator - (SCALAR_TYPE first, LLUnit<UNIT_TYPE,
return result;
}
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
+LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator - (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2> second)
+{
+ LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> result(first);
+ result -= second;
+ return result;
+}
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator - (LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second)
+{
+ LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> result(first);
+ result -= second;
+ return result;
+}
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator - (SCALAR_TYPE first, LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> second)
+{
+ LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> result(first);
+ result -= second;
+ return result;
+}
+
//
// operator *
//
@@ -278,6 +317,26 @@ LLUnit<UNIT_TYPE1, STORAGE_TYPE1> operator * (LLUnit<UNIT_TYPE1, STORAGE_TYPE1>,
return LLUnit<UNIT_TYPE1, STORAGE_TYPE1>();
}
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator * (SCALAR_TYPE first, LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> second)
+{
+ return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>(first * second.value());
+}
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator * (LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second)
+{
+ return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>(first.value() * second);
+}
+
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
+LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator * (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1>, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2>)
+{
+ // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
+ llstatic_assert(sizeof(STORAGE_TYPE1) == 0, "Multiplication of unit types results in new unit type - not supported.");
+ return LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1>();
+}
+
//
// operator /
//
@@ -300,23 +359,42 @@ STORAGE_TYPE1 operator / (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_T
return STORAGE_TYPE1(first.value() / second.value());
}
-#define COMPARISON_OPERATORS(op) \
-template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> \
-bool operator op (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second) \
-{ \
- return first op second.value(); \
-} \
- \
-template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> \
-bool operator op (LLUnit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) \
-{ \
- return first.value() op second; \
-} \
- \
-template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> \
-bool operator op (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second) \
-{ \
- return first.value() op first.convert(second); \
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator / (LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second)
+{
+ return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>(first.value() / second);
+}
+
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>
+STORAGE_TYPE1 operator / (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2> second)
+{
+ // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
+ return STORAGE_TYPE1(first.value() / second.value());
+}
+
+#define COMPARISON_OPERATORS(op) \
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> \
+bool operator op (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second) \
+{ \
+ return first op second.value(); \
+} \
+ \
+template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> \
+bool operator op (LLUnit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) \
+{ \
+ return first.value() op second; \
+} \
+ \
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> \
+bool operator op (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2> second) \
+{ \
+ return first.value() op first.convert(second); \
+} \
+ \
+template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> \
+ bool operator op (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second) \
+{ \
+ return first.value() op first.convert(second); \
}
COMPARISON_OPERATORS(<)
@@ -328,6 +406,15 @@ COMPARISON_OPERATORS(!=)
namespace LLUnits
{
+template<typename T>
+T rawValue(T val) { return val; }
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE>
+STORAGE_TYPE rawValue(LLUnit<UNIT_TYPE, STORAGE_TYPE> val) { return val.value(); }
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE>
+STORAGE_TYPE rawValue(LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> val) { return val.value(); }
+
template<typename UNIT_TYPE, typename STORAGE_TYPE>
struct HighestPrecisionType<LLUnit<UNIT_TYPE, STORAGE_TYPE> >
{
@@ -361,22 +448,22 @@ struct Bytes { typedef Bytes base_unit_t; };
LL_DECLARE_DERIVED_UNIT(1024, Bytes, Kilobytes);
LL_DECLARE_DERIVED_UNIT(1024 * 1024, Bytes, Megabytes);
LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024, Bytes, Gigabytes);
-LL_DECLARE_DERIVED_UNIT((1.0 / 8.0), Bytes, Bits);
-LL_DECLARE_DERIVED_UNIT((1024 / 8), Bytes, Kilobits);
-LL_DECLARE_DERIVED_UNIT((1024 / 8), Bytes, Megabits);
-LL_DECLARE_DERIVED_UNIT((1024 * 1024 * 1024 / 8), Bytes, Gigabits);
+LL_DECLARE_DERIVED_UNIT(1.0 / 8.0, Bytes, Bits);
+LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Kilobits);
+LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Megabits);
+LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024 / 8, Bytes, Gigabits);
struct Seconds { typedef Seconds base_unit_t; };
LL_DECLARE_DERIVED_UNIT(60, Seconds, Minutes);
LL_DECLARE_DERIVED_UNIT(60 * 60, Seconds, Hours);
-LL_DECLARE_DERIVED_UNIT((1.0 / 1000.0), Seconds, Milliseconds);
-LL_DECLARE_DERIVED_UNIT((1.0 / (1000000.0)), Seconds, Microseconds);
-LL_DECLARE_DERIVED_UNIT((1.0 / (1000000000.0)), Seconds, Nanoseconds);
+LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Seconds, Milliseconds);
+LL_DECLARE_DERIVED_UNIT(1.0 / 1000000.0, Seconds, Microseconds);
+LL_DECLARE_DERIVED_UNIT(1.0 / 1000000000.0, Seconds, Nanoseconds);
struct Meters { typedef Meters base_unit_t; };
LL_DECLARE_DERIVED_UNIT(1000, Meters, Kilometers);
-LL_DECLARE_DERIVED_UNIT((1.0 / 100.0), Meters, Centimeters);
-LL_DECLARE_DERIVED_UNIT((1.0 / 1000.0), Meters, Millimeters);
+LL_DECLARE_DERIVED_UNIT(1.0 / 100.0, Meters, Centimeters);
+LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Meters, Millimeters);
struct Hertz { typedef Hertz base_unit_t; };
LL_DECLARE_DERIVED_UNIT(1000, Hertz, Kilohertz);
diff --git a/indra/llcommon/tests/llunit_test.cpp b/indra/llcommon/tests/llunits_test.cpp
index a7e9c00740..2a941e8229 100644
--- a/indra/llcommon/tests/llunit_test.cpp
+++ b/indra/llcommon/tests/llunits_test.cpp
@@ -68,7 +68,7 @@ namespace tut
ensure(int_quatloos.value() == 42);
float_quatloos = 42.1f;
- ensure(float_quatloos == 42.1f);
+ ensure(float_quatloos.value() == 42.1f);
int_quatloos = float_quatloos;
ensure(int_quatloos.value() == 42);
LLUnit<Quatloos, U32> unsigned_int_quatloos(float_quatloos);
@@ -153,4 +153,56 @@ namespace tut
quatloos -= LLUnit<Latinum, F32>(1.f);
ensure(quatloos.value() == 1);
}
+
+ // implicit units
+ template<> template<>
+ void units_object_t::test<5>()
+ {
+ // 0-initialized
+ LLUnit<Quatloos, F32> quatloos(0);
+ // initialize implicit unit from explicit
+ LLUnitImplicit<Quatloos, F32> quatloos_implicit = quatloos + 1;
+ ensure(quatloos_implicit.value() == 1);
+
+ // assign implicit to explicit, or perform math operations
+ quatloos = quatloos_implicit;
+ ensure(quatloos.value() == 1);
+ quatloos += quatloos_implicit;
+ ensure(quatloos.value() == 2);
+
+ // math operations on implicits
+ quatloos_implicit = 1;
+ ensure(quatloos_implicit == 1);
+
+ quatloos_implicit += 2;
+ ensure(quatloos_implicit == 3);
+
+ quatloos_implicit *= 2;
+ ensure(quatloos_implicit == 6);
+
+ quatloos_implicit -= 1;
+ ensure(quatloos_implicit == 5);
+
+ quatloos_implicit /= 5;
+ ensure(quatloos_implicit == 1);
+
+ quatloos_implicit = quatloos_implicit + 3 + quatloos_implicit;
+ ensure(quatloos_implicit == 5);
+
+ quatloos_implicit = 10 - quatloos_implicit - 1;
+ ensure(quatloos_implicit == 4);
+
+ quatloos_implicit = 2 * quatloos_implicit * 2;
+ ensure(quatloos_implicit == 16);
+
+ F32 one_half = quatloos_implicit / (quatloos_implicit * 2);
+ ensure(one_half == 0.5f);
+
+ // implicit conversion to POD
+ F32 float_val = quatloos_implicit;
+ ensure(float_val == 16);
+
+ S32 int_val = quatloos_implicit;
+ ensure(int_val == 16);
+ }
}
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 704b914b78..1c63022527 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -311,11 +311,11 @@ static std::string get_tooltip(LLTrace::TimeBlock& timer, S32 history_index, LLT
if (history_index < 0)
{
// by default, show average number of call
- tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(frame_recording.getPeriodMean(timer) * ms_multiplier), (S32)frame_recording.getPeriodMean(timer.callCount()));
+ tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(frame_recording.getPeriodMean(timer) * ms_multiplier).value(), (S32)frame_recording.getPeriodMean(timer.callCount()));
}
else
{
- tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(frame_recording.getPrevRecordingPeriod(history_index).getSum(timer) * ms_multiplier), (S32)frame_recording.getPrevRecordingPeriod(history_index).getSum(timer.callCount()));
+ tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(frame_recording.getPrevRecordingPeriod(history_index).getSum(timer) * ms_multiplier).value(), (S32)frame_recording.getPrevRecordingPeriod(history_index).getSum(timer.callCount()));
}
return tooltip;
}
@@ -601,22 +601,22 @@ void LLFastTimerView::draw()
{
LLUnit<LLUnits::Milliseconds, U32> ms = total_time;
- tdesc = llformat("%.1f ms |", (F32)ms*.25f);
+ tdesc = llformat("%.1f ms |", (F32)ms.value()*.25f);
x = xleft + barw/4 - LLFontGL::getFontMonospace()->getWidth(tdesc);
LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white,
LLFontGL::LEFT, LLFontGL::TOP);
- tdesc = llformat("%.1f ms |", (F32)ms*.50f);
+ tdesc = llformat("%.1f ms |", (F32)ms.value()*.50f);
x = xleft + barw/2 - LLFontGL::getFontMonospace()->getWidth(tdesc);
LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white,
LLFontGL::LEFT, LLFontGL::TOP);
- tdesc = llformat("%.1f ms |", (F32)ms*.75f);
+ tdesc = llformat("%.1f ms |", (F32)ms.value()*.75f);
x = xleft + (barw*3)/4 - LLFontGL::getFontMonospace()->getWidth(tdesc);
LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white,
LLFontGL::LEFT, LLFontGL::TOP);
- tdesc = llformat( "%d ms |", (U32)ms);
+ tdesc = llformat( "%d ms |", (U32)ms.value());
x = xleft + barw - LLFontGL::getFontMonospace()->getWidth(tdesc);
LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white,
LLFontGL::LEFT, LLFontGL::TOP);
@@ -728,11 +728,11 @@ void LLFastTimerView::draw()
++it)
{
sublevelticks += (tidx == -1)
- ? frame_recording.getPeriodMean(**it)
- : frame_recording.getPrevRecordingPeriod(tidx).getSum(**it);
+ ? frame_recording.getPeriodMean(**it).value()
+ : frame_recording.getPrevRecordingPeriod(tidx).getSum(**it).value();
}
- F32 subfrac = (F32)sublevelticks / (F32)total_time;
+ F32 subfrac = (F32)sublevelticks / (F32)total_time.value();
sublevel_dx[level] = (int)(subfrac * (F32)barw + .5f);
if (mDisplayCenter == ALIGN_CENTER)
@@ -819,7 +819,7 @@ void LLFastTimerView::draw()
else if (mDisplayHz)
tdesc = llformat("%d Hz", (int)(1.f / max_time.value()));
else
- tdesc = llformat("%4.2f ms", LLUnit<LLUnits::Milliseconds, F32>(max_time).value());
+ tdesc = llformat("%4.2f ms", max_time.value());
x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(tdesc)-5;
y = mGraphRect.mTop - LLFontGL::getFontMonospace()->getLineHeight();
@@ -900,7 +900,7 @@ void LLFastTimerView::draw()
F32 x = mGraphRect.mRight - j * (F32)(mGraphRect.getWidth())/(LLTrace::TimeBlock::HISTORY_NUM-1);
F32 y = mDisplayHz
? mGraphRect.mBottom + (1.f / time.value()) * ((F32) mGraphRect.getHeight() / (1.f / max_time.value()))
- : mGraphRect.mBottom + time * ((F32)mGraphRect.getHeight() / max_time);
+ : mGraphRect.mBottom + time / max_time * (F32)mGraphRect.getHeight();
gGL.vertex2f(x,y);
gGL.vertex2f(x,mGraphRect.mBottom);
}
@@ -920,22 +920,22 @@ void LLFastTimerView::draw()
}
//interpolate towards new maximum
- max_time = lerp((F32)max_time, (F32) cur_max, LLCriticalDamp::getInterpolant(0.1f));
+ max_time = lerp(max_time.value(), cur_max.value(), LLCriticalDamp::getInterpolant(0.1f));
if (max_time - cur_max <= 1 || cur_max - max_time <= 1)
{
max_time = llmax(LLUnit<LLUnits::Microseconds, F32>(1), LLUnit<LLUnits::Microseconds, F32>(cur_max));
}
max_calls = lerp((F32)max_calls, (F32) cur_max_calls, LLCriticalDamp::getInterpolant(0.1f));
- if (llabs(max_calls - cur_max) <= 1)
+ if (llabs((S32)(max_calls - cur_max_calls)) <= 1)
{
max_calls = cur_max_calls;
}
// TODO: make sure alpha is correct in DisplayHz mode
F32 alpha_target = (max_time > cur_max)
- ? llmin((F32) max_time/ (F32) cur_max - 1.f,1.f)
- : llmin((F32) cur_max/ (F32) max_time - 1.f,1.f);
+ ? llmin(max_time / cur_max - 1.f,1.f)
+ : llmin(cur_max/ max_time - 1.f,1.f);
alpha_interp = lerp(alpha_interp, alpha_target, LLCriticalDamp::getInterpolant(0.1f));
if (mHoverID != NULL)
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 813fc7db6a..3be19c3920 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2747,7 +2747,7 @@ void LLPipeline::updateGeom(F32 max_dtime)
S32 count = 0;
- max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, LLUnit<LLUnits::Seconds, F32>(max_dtime));
+ max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, LLUnitImplicit<LLUnits::Seconds, F32>(max_dtime));
LLSpatialGroup* last_group = NULL;
LLSpatialBridge* last_bridge = NULL;