Commit f0dd087e by Shahbaz Youssefi Committed by Commit Bot

Move timer functionality from util/ to common/

The main timer functionality (get absolute time) is moved to common/ for use in ANGLE itself (in upcoming overlay change). util/Timer.h is no longer an abstract class and uses this functionality to implement the timer. Bug: angleproject:3757 Change-Id: I3fe418778d80d1089c9bfe43a9e8098e43236f18 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1769061Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent eb68081e
......@@ -68,7 +68,6 @@ SampleApplication::SampleApplication(std::string name,
angle::OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, angle::SearchType::ApplicationDir));
mEGLWindow = EGLWindow::New(glesMajorVersion, glesMinorVersion);
mTimer.reset(CreateTimer());
mOSWindow = OSWindow::New();
}
......@@ -158,12 +157,12 @@ int SampleApplication::run()
result = -1;
}
mTimer->start();
mTimer.start();
double prevTime = 0.0;
while (mRunning)
{
double elapsedTime = mTimer->getElapsedTime();
double elapsedTime = mTimer.getElapsedTime();
double deltaTime = elapsedTime - prevTime;
step(static_cast<float>(deltaTime), elapsedTime);
......
......@@ -61,7 +61,7 @@ class SampleApplication
uint32_t mHeight;
bool mRunning;
std::unique_ptr<Timer> mTimer;
Timer mTimer;
EGLWindow *mEGLWindow;
OSWindow *mOSWindow;
......
......@@ -130,12 +130,6 @@ void main()
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
mOrigTimer = CreateTimer();
mResizeDrawTimer = CreateTimer();
mResizeDefineTimer = CreateTimer();
mNewTexDrawTimer = CreateTimer();
mNewTexDefineTimer = CreateTimer();
return true;
}
......@@ -191,54 +185,54 @@ void main()
// unreleated to texture creation. mTimeFrame is set to true on the fifth frame.
if (mTimeFrame)
{
mOrigTimer->start();
mOrigTimer.start();
}
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
if (mTimeFrame)
{
mOrigTimer->stop();
mOrigTimer.stop();
// This timer indicates draw time for an already-created texture resident on the GPU,
// which needs no updates. It will be faster than the other draws.
std::cout << "Original texture draw: " << mOrigTimer->getElapsedTime() * 1000 << "msec"
std::cout << "Original texture draw: " << mOrigTimer.getElapsedTime() * 1000 << "msec"
<< std::endl;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Now, change the texture dimensions of the original texture
mResizeDefineTimer->start();
mResizeDefineTimer.start();
defineSquareTexture2D(mTextureIds[0], 512, GL_RGBA, GL_UNSIGNED_BYTE, mPixelsResize);
mResizeDefineTimer->stop();
mResizeDefineTimer.stop();
mResizeDrawTimer->start();
mResizeDrawTimer.start();
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
mResizeDrawTimer->stop();
mResizeDrawTimer.stop();
// This timer indicates draw time for a texture which has already been used in a draw,
// causing the underlying resource to be allocated, and then resized, requiring resource
// reallocation and related overhead.
std::cout << "Resized texture definition: "
<< mResizeDefineTimer->getElapsedTime() * 1000 << "msec" << std::endl;
std::cout << "Resized texture draw: " << mResizeDrawTimer->getElapsedTime() * 1000
<< mResizeDefineTimer.getElapsedTime() * 1000 << "msec" << std::endl;
std::cout << "Resized texture draw: " << mResizeDrawTimer.getElapsedTime() * 1000
<< "msec" << std::endl;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Create texure at same dimensions we resized previous texture to
mNewTexDefineTimer->start();
mNewTexDefineTimer.start();
defineSquareTexture2D(mTextureIds[1], 512, GL_RGBA, GL_UNSIGNED_BYTE, mPixelsNewTex);
mNewTexDefineTimer->stop();
mNewTexDefineTimer.stop();
mNewTexDrawTimer->start();
mNewTexDrawTimer.start();
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
mNewTexDrawTimer->stop();
mNewTexDrawTimer.stop();
// This timer indicates draw time for a texture newly created this frame. The underlying
// resource will need to be created, but because it has not previously been used, there
// is no already-resident texture object to manage. This draw is expected to be faster
// than the resized texture draw.
std::cout << "Newly created texture definition: "
<< mNewTexDefineTimer->getElapsedTime() * 1000 << "msec" << std::endl;
std::cout << "Newly created texture draw: " << mNewTexDrawTimer->getElapsedTime() * 1000
<< mNewTexDefineTimer.getElapsedTime() * 1000 << "msec" << std::endl;
std::cout << "Newly created texture draw: " << mNewTexDrawTimer.getElapsedTime() * 1000
<< "msec" << std::endl;
}
......@@ -269,11 +263,11 @@ void main()
GLubyte *mPixelsResize;
GLubyte *mPixelsNewTex;
Timer *mOrigTimer;
Timer *mResizeDrawTimer;
Timer *mResizeDefineTimer;
Timer *mNewTexDrawTimer;
Timer *mNewTexDefineTimer;
Timer mOrigTimer;
Timer mResizeDrawTimer;
Timer mResizeDefineTimer;
Timer mNewTexDrawTimer;
Timer mNewTexDefineTimer;
bool mTimeFrame;
unsigned int mFrameCount;
};
......
......@@ -157,8 +157,6 @@ void main()
createVertexBuffers();
mFanTimer = CreateTimer();
mTriTimer = CreateTimer();
mFanTotalTime = 0;
mTriTotalTime = 0;
......@@ -191,33 +189,33 @@ void main()
glEnableVertexAttribArray(0);
// Draw using triangle fans, stored in VBO
mFanTimer->start();
mFanTimer.start();
for (unsigned i = 0; i < mNumSquares; ++i)
{
glBindBuffer(GL_ARRAY_BUFFER, mFanBufId[i]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glDrawArrays(GL_TRIANGLE_FAN, 0, mNumFanVerts);
}
mFanTimer->stop();
mFanTimer.stop();
mFanTotalTime += static_cast<unsigned int>(
mFanTimer->getElapsedTime() * 1000); // convert from usec to msec when accumulating
mFanTimer.getElapsedTime() * 1000); // convert from usec to msec when accumulating
// Clear to eliminate driver-side gains from occlusion
glClear(GL_COLOR_BUFFER_BIT);
// Draw using triangles, stored in VBO
mTriTimer->start();
mTriTimer.start();
for (unsigned i = 1; i < mNumSquares; ++i)
{
glBindBuffer(GL_ARRAY_BUFFER, mTriBufId[i]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glDrawArrays(GL_TRIANGLES, 0, mNumTriVerts);
}
mTriTimer->stop();
mTriTimer.stop();
mTriTotalTime += static_cast<unsigned int>(
mTriTimer->getElapsedTime() * 1000); // convert from usec to msec when accumulating
mTriTimer.getElapsedTime() * 1000); // convert from usec to msec when accumulating
mFrameCount++;
}
......@@ -230,8 +228,8 @@ void main()
GLuint mFanBufId[mNumSquares];
GLuint mTriBufId[mNumSquares];
Timer *mFanTimer;
Timer *mTriTimer;
Timer mFanTimer;
Timer mTriTimer;
unsigned int mFrameCount;
unsigned int mTriTotalTime;
unsigned int mFanTotalTime;
......
......@@ -26,6 +26,9 @@ const char *GetPathSeparator();
bool PrependPathToEnvironmentVar(const char *variableName, const char *path);
bool IsDirectory(const char *filename);
// Get absolute time in seconds. Use this function to get an absolute time with an unknown origin.
double GetCurrentTime();
// Run an application and get the output. Gets a nullptr-terminated set of args to execute the
// application with, and returns the stdout and stderr outputs as well as the exit code.
//
......
......@@ -44,4 +44,12 @@ const char *GetSharedLibraryExtension()
{
return "so";
}
double GetCurrentTime()
{
struct timespec currentTime;
clock_gettime(CLOCK_MONOTONIC, &currentTime);
return currentTime.tv_sec + currentTime.tv_nsec * 1e-9;
}
} // namespace angle
......@@ -10,7 +10,10 @@
#include <unistd.h>
#include <CoreServices/CoreServices.h>
#include <mach-o/dyld.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <cstdlib>
#include <vector>
......@@ -49,4 +52,13 @@ const char *GetSharedLibraryExtension()
{
return "dylib";
}
double GetCurrentTime()
{
mach_timebase_info_data_t timebaseInfo;
mach_timebase_info(&timebaseInfo);
double secondCoeff = timebaseInfo.numer * 1e-9 / timebaseInfo.denom;
return secondCoeff * mach_absolute_time();
}
} // namespace angle
......@@ -131,6 +131,17 @@ const char *GetPathSeparator()
return ";";
}
double GetCurrentTime()
{
LARGE_INTEGER frequency = {};
QueryPerformanceFrequency(&frequency);
LARGE_INTEGER curTime;
QueryPerformanceCounter(&curTime);
return static_cast<double>(curTime.QuadPart) / frequency.QuadPart;
}
bool RunApp(const std::vector<const char *> &args,
std::string *stdoutOut,
std::string *stderrOut,
......
......@@ -376,28 +376,28 @@ TEST_P(EGLSurfaceTest, SwapInterval)
{
if (maxInterval >= 1)
{
std::unique_ptr<Timer> timer(CreateTimer());
Timer timer;
eglSwapInterval(mDisplay, 1);
timer->start();
timer.start();
for (int i = 0; i < 180; ++i)
{
eglSwapBuffers(mDisplay, mWindowSurface);
}
timer->stop();
timer.stop();
ASSERT_EGL_SUCCESS();
// 120 frames at 60fps should take 3s. At lower fps, it should take even longer. At
// 144fps, it would take 1.25s. Let's use 1s as a lower bound.
ASSERT_GT(timer->getElapsedTime(), 1);
ASSERT_GT(timer.getElapsedTime(), 1);
}
if (minInterval <= 0)
{
std::unique_ptr<Timer> timer(CreateTimer());
Timer timer;
eglSwapInterval(mDisplay, 0);
timer->start();
timer.start();
for (int i = 0; i < 100; ++i)
{
eglSwapBuffers(mDisplay, mWindowSurface);
......@@ -406,7 +406,7 @@ TEST_P(EGLSurfaceTest, SwapInterval)
// http://anglebug.com/3144.
ANGLE_SKIP_TEST_IF(IsNVIDIAShield());
}
timer->stop();
timer.stop();
ASSERT_EGL_SUCCESS();
// 100 no-op swaps should be fairly fast, though there is no guarantee how fast it can
......@@ -415,7 +415,7 @@ TEST_P(EGLSurfaceTest, SwapInterval)
// TODO(syoussefi): if a surface doesn't truly allow no-vsync, this can fail. Until
// there's a way to query the exact minInterval from the surface, this test cannot be
// enabled.
// ASSERT_LT(timer->getElapsedTime(), 1);
// ASSERT_LT(timer.getElapsedTime(), 1);
}
}
}
......
......@@ -113,11 +113,10 @@ void UpdateTraceEventDuration(angle::PlatformMethods *platform,
double MonotonicallyIncreasingTime(angle::PlatformMethods *platform)
{
ANGLERenderTest *renderTest = static_cast<ANGLERenderTest *>(platform->context);
// Move the time origin to the first call to this function, to avoid generating unnecessarily
// large timestamps.
static double origin = renderTest->getTimer()->getAbsoluteTime();
return renderTest->getTimer()->getAbsoluteTime() - origin;
static double origin = angle::GetCurrentTime();
return angle::GetCurrentTime() - origin;
}
void DumpTraceEventsToJSONFile(const std::vector<TraceEvent> &traceEvents,
......@@ -165,7 +164,6 @@ ANGLEPerfTest::ANGLEPerfTest(const std::string &name,
: mName(name),
mBackend(backend),
mStory(story),
mTimer(CreateTimer()),
mGPUTimeNs(0),
mSkipTest(false),
mStepsToRun(std::numeric_limits<unsigned int>::max()),
......@@ -189,7 +187,6 @@ ANGLEPerfTest::ANGLEPerfTest(const std::string &name,
ANGLEPerfTest::~ANGLEPerfTest()
{
SafeDelete(mTimer);
}
void ANGLEPerfTest::run()
......@@ -205,7 +202,7 @@ void ANGLEPerfTest::run()
doRunLoop(kCalibrationRunTimeSeconds);
// Scale steps down according to the time that exeeded one second.
double scale = kCalibrationRunTimeSeconds / mTimer->getElapsedTime();
double scale = kCalibrationRunTimeSeconds / mTimer.getElapsedTime();
mStepsToRun = static_cast<size_t>(static_cast<double>(mNumStepsPerformed) * scale);
// Calibration allows the perf test runner script to save some time.
......@@ -235,7 +232,7 @@ void ANGLEPerfTest::doRunLoop(double maxRunTime)
{
mNumStepsPerformed = 0;
mRunning = true;
mTimer->start();
mTimer.start();
startTest();
while (mRunning)
......@@ -244,7 +241,7 @@ void ANGLEPerfTest::doRunLoop(double maxRunTime)
if (mRunning)
{
++mNumStepsPerformed;
if (mTimer->getElapsedTime() > maxRunTime)
if (mTimer.getElapsedTime() > maxRunTime)
{
mRunning = false;
}
......@@ -255,7 +252,7 @@ void ANGLEPerfTest::doRunLoop(double maxRunTime)
}
}
finishTest();
mTimer->stop();
mTimer.stop();
}
void ANGLEPerfTest::SetUp() {}
......@@ -265,7 +262,7 @@ void ANGLEPerfTest::TearDown() {}
double ANGLEPerfTest::printResults()
{
double elapsedTimeSeconds[2] = {
mTimer->getElapsedTime(),
mTimer.getElapsedTime(),
mGPUTimeNs * 1e-9,
};
......
......@@ -69,8 +69,6 @@ class ANGLEPerfTest : public testing::Test, angle::NonCopyable
// Called right before timer is stopped to let the test wait for asynchronous operations.
virtual void finishTest() {}
Timer *getTimer() const { return mTimer; }
protected:
void run();
void SetUp() override;
......@@ -88,7 +86,7 @@ class ANGLEPerfTest : public testing::Test, angle::NonCopyable
std::string mName;
std::string mBackend;
std::string mStory;
Timer *mTimer;
Timer mTimer;
uint64_t mGPUTimeNs;
bool mSkipTest;
std::unique_ptr<perf_test::PerfResultReporter> mReporter;
......
......@@ -20,7 +20,7 @@ namespace
// Only applies to D3D11
struct Captures final : private angle::NonCopyable
{
Timer *timer = CreateTimer();
Timer timer;
size_t loadDLLsMS = 0;
size_t createDeviceMS = 0;
size_t initResourcesMS = 0;
......@@ -29,7 +29,7 @@ struct Captures final : private angle::NonCopyable
double CapturePlatform_currentTime(angle::PlatformMethods *platformMethods)
{
Captures *captures = static_cast<Captures *>(platformMethods->context);
return captures->timer->getElapsedTime();
return captures->timer.getElapsedTime();
}
void CapturePlatform_histogramCustomCounts(angle::PlatformMethods *platformMethods,
......
......@@ -276,7 +276,7 @@ void InstancingPerfBenchmark::drawBenchmark()
// Animatino makes the test more interesting visually, but also eats up many CPU cycles.
if (params.animationEnabled)
{
float time = static_cast<float>(mTimer->getElapsedTime());
float time = static_cast<float>(mTimer.getElapsedTime());
for (size_t pointIndex = 0; pointIndex < mTranslateData.size(); ++pointIndex)
{
......
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Timer.cpp: Implementation of a high precision timer class.
//
#include "util/Timer.h"
#include "common/system_utils.h"
Timer::Timer() : mRunning(false), mStartTime(0), mStopTime(0) {}
void Timer::start()
{
mStartTime = angle::GetCurrentTime();
mRunning = true;
}
void Timer::stop()
{
mStopTime = angle::GetCurrentTime();
mRunning = false;
}
double Timer::getElapsedTime() const
{
double endTime;
if (mRunning)
{
endTime = angle::GetCurrentTime();
}
else
{
endTime = mStopTime;
}
return endTime - mStartTime;
}
//
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -9,23 +9,23 @@
#include "util/util_export.h"
class ANGLE_UTIL_EXPORT Timer
class ANGLE_UTIL_EXPORT Timer final
{
public:
virtual ~Timer() {}
Timer();
~Timer() {}
// Timer functionality: Use start() and stop() to record the duration and use getElapsedTime()
// to query that duration. If getElapsedTime() is called in between, it will report the elapsed
// time since start().
virtual void start() = 0;
virtual void stop() = 0;
virtual double getElapsedTime() const = 0;
// Use start() and stop() to record the duration and use getElapsedTime() to query that
// duration. If getElapsedTime() is called in between, it will report the elapsed time since
// start().
void start();
void stop();
double getElapsedTime() const;
// Timestamp functionality: Use getAbsoluteTime() to get an absolute time with an unknown
// origin. This time moves forward regardless of start()/stop().
virtual double getAbsoluteTime() = 0;
private:
bool mRunning;
double mStartTime;
double mStopTime;
};
ANGLE_UTIL_EXPORT Timer *CreateTimer();
#endif // SAMPLE_UTIL_TIMER_H
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// OSXTimer.cpp: Implementation of a high precision timer class on OSX
#include "util/osx/OSXTimer.h"
#include <CoreServices/CoreServices.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
OSXTimer::OSXTimer() : mRunning(false), mSecondCoeff(0) {}
double OSXTimer::getSecondCoeff()
{
// If this is the first time we've run, get the timebase.
if (mSecondCoeff == 0.0)
{
mach_timebase_info_data_t timebaseInfo;
mach_timebase_info(&timebaseInfo);
mSecondCoeff = timebaseInfo.numer * (1.0 / 1000000000) / timebaseInfo.denom;
}
return mSecondCoeff;
}
void OSXTimer::start()
{
mStartTime = mach_absolute_time();
// Cache secondCoeff
getSecondCoeff();
mRunning = true;
}
void OSXTimer::stop()
{
mStopTime = mach_absolute_time();
mRunning = false;
}
double OSXTimer::getElapsedTime() const
{
if (mRunning)
{
return mSecondCoeff * (mach_absolute_time() - mStartTime);
}
else
{
return mSecondCoeff * (mStopTime - mStartTime);
}
}
double OSXTimer::getAbsoluteTime()
{
return getSecondCoeff() * mach_absolute_time();
}
Timer *CreateTimer()
{
return new OSXTimer();
}
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// OSXTimer.h: Definition of a high precision timer class on OSX
#ifndef UTIL_OSX_TIMER_H_
#define UTIL_OSX_TIMER_H_
#include <stdint.h>
#include <time.h>
#include "util/Timer.h"
class ANGLE_UTIL_EXPORT OSXTimer : public Timer
{
public:
OSXTimer();
void start() override;
void stop() override;
double getElapsedTime() const override;
double getAbsoluteTime() override;
private:
double getSecondCoeff();
bool mRunning;
uint64_t mStartTime;
uint64_t mStopTime;
double mSecondCoeff;
};
#endif // UTIL_OSX_TIMER_H_
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// PosixTimer.cpp: Implementation of a high precision timer class on POSIX
#include "util/posix/PosixTimer.h"
#include <iostream>
PosixTimer::PosixTimer() : mRunning(false) {}
namespace
{
uint64_t getCurrentTimeNs()
{
struct timespec currentTime;
clock_gettime(CLOCK_MONOTONIC, &currentTime);
return currentTime.tv_sec * 1'000'000'000llu + currentTime.tv_nsec;
}
} // anonymous namespace
void PosixTimer::start()
{
mStartTimeNs = getCurrentTimeNs();
mRunning = true;
}
void PosixTimer::stop()
{
mStopTimeNs = getCurrentTimeNs();
mRunning = false;
}
double PosixTimer::getElapsedTime() const
{
uint64_t endTimeNs;
if (mRunning)
{
endTimeNs = getCurrentTimeNs();
}
else
{
endTimeNs = mStopTimeNs;
}
return (endTimeNs - mStartTimeNs) * 1e-9;
}
double PosixTimer::getAbsoluteTime()
{
return getCurrentTimeNs() * 1e-9;
}
Timer *CreateTimer()
{
return new PosixTimer();
}
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// PosixTimer.h: Definition of a high precision timer class on Linux
#ifndef UTIL_POSIX_TIMER_H
#define UTIL_POSIX_TIMER_H
#include <stdint.h>
#include <time.h>
#include "util/Timer.h"
class ANGLE_UTIL_EXPORT PosixTimer : public Timer
{
public:
PosixTimer();
void start() override;
void stop() override;
double getElapsedTime() const override;
double getAbsoluteTime() override;
private:
bool mRunning;
uint64_t mStartTimeNs;
uint64_t mStopTimeNs;
};
#endif // UTIL_POSIX_TIMER_H
......@@ -24,6 +24,7 @@ util_sources = [
"util/OSWindow.cpp",
"util/OSWindow.h",
"util/Timer.h",
"util/Timer.cpp",
]
util_win_sources = [
......@@ -33,16 +34,12 @@ util_win_sources = [
"util/windows/win32/Win32Window.cpp",
"util/windows/win32/Win32Window.h",
"util/windows/Windows_system_utils.cpp",
"util/windows/WindowsTimer.cpp",
"util/windows/WindowsTimer.h",
"util/windows/WGLWindow.h",
]
util_win_shared_sources = [ "util/windows/WGLWindow.cpp" ]
util_posix_sources = [
"util/posix/PosixTimer.cpp",
"util/posix/PosixTimer.h",
"util/posix/Posix_crash_handler.cpp",
"util/posix/Posix_system_utils.cpp",
]
......@@ -68,8 +65,6 @@ util_ozone_sources = [
]
util_osx_sources = [
"util/osx/OSXTimer.cpp",
"util/osx/OSXTimer.h",
"util/osx/OSXPixmap.mm",
"util/osx/OSXPixmap.h",
"util/osx/OSXWindow.mm",
......
//
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// WindowsTimer.cpp: Implementation of a high precision timer class on Windows
#include "util/windows/WindowsTimer.h"
WindowsTimer::WindowsTimer() : mRunning(false), mStartTime(0), mStopTime(0), mFrequency(0) {}
LONGLONG WindowsTimer::getFrequency()
{
if (mFrequency == 0)
{
LARGE_INTEGER frequency = {};
QueryPerformanceFrequency(&frequency);
mFrequency = frequency.QuadPart;
}
return mFrequency;
}
void WindowsTimer::start()
{
LARGE_INTEGER curTime;
QueryPerformanceCounter(&curTime);
mStartTime = curTime.QuadPart;
// Cache the frequency
getFrequency();
mRunning = true;
}
void WindowsTimer::stop()
{
LARGE_INTEGER curTime;
QueryPerformanceCounter(&curTime);
mStopTime = curTime.QuadPart;
mRunning = false;
}
double WindowsTimer::getElapsedTime() const
{
LONGLONG endTime;
if (mRunning)
{
LARGE_INTEGER curTime;
QueryPerformanceCounter(&curTime);
endTime = curTime.QuadPart;
}
else
{
endTime = mStopTime;
}
return static_cast<double>(endTime - mStartTime) / mFrequency;
}
double WindowsTimer::getAbsoluteTime()
{
LARGE_INTEGER curTime;
QueryPerformanceCounter(&curTime);
return static_cast<double>(curTime.QuadPart) / getFrequency();
}
Timer *CreateTimer()
{
return new WindowsTimer();
}
//
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// WindowsTimer.h: Definition of a high precision timer class on Windows
#ifndef UTIL_WINDOWS_TIMER_H
#define UTIL_WINDOWS_TIMER_H
#include <windows.h>
#include "util/Timer.h"
class ANGLE_UTIL_EXPORT WindowsTimer : public Timer
{
public:
WindowsTimer();
void start() override;
void stop() override;
double getElapsedTime() const override;
double getAbsoluteTime() override;
private:
LONGLONG getFrequency();
bool mRunning;
LONGLONG mStartTime;
LONGLONG mStopTime;
LONGLONG mFrequency;
};
#endif // UTIL_WINDOWS_TIMER_H
......@@ -486,7 +486,6 @@ LRESULT CALLBACK Win32Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LP
Win32Window::Win32Window()
: mIsVisible(false),
mSetVisibleTimer(CreateTimer()),
mIsMouseInWindow(false),
mNativeWindow(0),
mParentWindow(0),
......@@ -496,7 +495,6 @@ Win32Window::Win32Window()
Win32Window::~Win32Window()
{
destroy();
delete mSetVisibleTimer;
}
bool Win32Window::initialize(const std::string &name, int width, int height)
......@@ -611,7 +609,7 @@ bool Win32Window::takeScreenshot(uint8_t *pixelData)
// for a while before issuing screenshot if window was just made visible.
{
static const double WAIT_WINDOW_VISIBLE_MS = 0.5; // Half a second for the animation
double timeSinceVisible = mSetVisibleTimer->getElapsedTime();
double timeSinceVisible = mSetVisibleTimer.getElapsedTime();
if (timeSinceVisible < WAIT_WINDOW_VISIBLE_MS)
{
......@@ -804,8 +802,8 @@ void Win32Window::setVisible(bool isVisible)
if (isVisible)
{
mSetVisibleTimer->stop();
mSetVisibleTimer->start();
mSetVisibleTimer.stop();
mSetVisibleTimer.start();
}
}
......
......@@ -48,7 +48,7 @@ class Win32Window : public OSWindow
std::string mChildClassName;
bool mIsVisible;
Timer *mSetVisibleTimer;
Timer mSetVisibleTimer;
bool mIsMouseInWindow;
......
......@@ -427,20 +427,18 @@ bool X11Window::resize(int width, int height)
XResizeWindow(mDisplay, mWindow, width, height);
XFlush(mDisplay);
Timer *timer = CreateTimer();
timer->start();
Timer timer;
timer.start();
// Wait until the window as actually been resized so that the code calling resize
// can assume the window has been resized.
const double kResizeWaitDelay = 0.2;
while ((mHeight != height || mWidth != width) && timer->getElapsedTime() < kResizeWaitDelay)
while ((mHeight != height || mWidth != width) && timer.getElapsedTime() < kResizeWaitDelay)
{
messageLoop();
angle::Sleep(10);
}
delete timer;
return true;
}
......
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