From 4ed75287aed6371c6e4a41ffcc78c8a49c9810ed Mon Sep 17 00:00:00 2001 From: mtklein Date: Fri, 20 Jun 2014 10:31:48 -0700 Subject: Move BenchTimer to tools as Timer This breaks a bunch of circular dependencies between tools and gm and bench. BUG=skia: R=tfarina@chromium.org, mtklein@google.com Author: mtklein@chromium.org Review URL: https://codereview.chromium.org/344213003 --- bench/BenchGpuTimer_gl.cpp | 74 --------- bench/BenchGpuTimer_gl.h | 26 --- bench/BenchSysTimer_c.cpp | 27 ---- bench/BenchSysTimer_c.h | 26 --- bench/BenchSysTimer_mach.cpp | 76 --------- bench/BenchSysTimer_mach.h | 26 --- bench/BenchSysTimer_posix.cpp | 57 ------- bench/BenchSysTimer_posix.h | 25 --- bench/BenchSysTimer_windows.cpp | 64 -------- bench/BenchSysTimer_windows.h | 26 --- bench/BenchTimer.cpp | 94 ----------- bench/BenchTimer.h | 67 -------- bench/TimerData.cpp | 224 -------------------------- bench/TimerData.h | 86 ---------- bench/benchmain.cpp | 6 +- debugger/QT/SkDebuggerGUI.cpp | 10 +- gyp/SampleApp.gyp | 2 +- gyp/apptype_console.gypi | 2 +- gyp/bench.gyp | 64 +------- gyp/crash_handler.gyp | 18 --- gyp/debugger.gyp | 2 +- gyp/dm.gyp | 2 +- gyp/gm.gyp | 27 +--- gyp/resources.gyp | 25 --- gyp/skia_launcher.gyp | 3 + gyp/tests.gyp | 2 +- gyp/tests.gypi | 2 +- gyp/tools.gyp | 107 +++++++++--- platform_tools/android/gyp/skia_android.gypi | 7 - platform_tools/android/gyp/skia_launcher.gypi | 7 + tools/DumpRecord.cpp | 4 +- tools/PictureBenchmark.cpp | 16 +- tools/PictureBenchmark.h | 4 +- tools/bbh_shootout.cpp | 8 +- tools/bench_pictures_main.cpp | 2 +- tools/bench_playback.cpp | 11 +- tools/bench_record.cpp | 22 +-- tools/skpdiff/skpdiff_util.cpp | 2 +- tools/timer/GpuTimer.cpp | 74 +++++++++ tools/timer/GpuTimer.h | 25 +++ tools/timer/SysTimer_mach.cpp | 66 ++++++++ tools/timer/SysTimer_mach.h | 24 +++ tools/timer/SysTimer_posix.cpp | 51 ++++++ tools/timer/SysTimer_posix.h | 23 +++ tools/timer/SysTimer_windows.cpp | 56 +++++++ tools/timer/SysTimer_windows.h | 25 +++ tools/timer/Timer.cpp | 53 ++++++ tools/timer/Timer.h | 73 +++++++++ tools/timer/TimerData.cpp | 220 +++++++++++++++++++++++++ tools/timer/TimerData.h | 85 ++++++++++ 50 files changed, 926 insertions(+), 1102 deletions(-) delete mode 100644 bench/BenchGpuTimer_gl.cpp delete mode 100644 bench/BenchGpuTimer_gl.h delete mode 100644 bench/BenchSysTimer_c.cpp delete mode 100644 bench/BenchSysTimer_c.h delete mode 100644 bench/BenchSysTimer_mach.cpp delete mode 100644 bench/BenchSysTimer_mach.h delete mode 100644 bench/BenchSysTimer_posix.cpp delete mode 100644 bench/BenchSysTimer_posix.h delete mode 100644 bench/BenchSysTimer_windows.cpp delete mode 100644 bench/BenchSysTimer_windows.h delete mode 100644 bench/BenchTimer.cpp delete mode 100644 bench/BenchTimer.h delete mode 100644 bench/TimerData.cpp delete mode 100644 bench/TimerData.h delete mode 100644 gyp/crash_handler.gyp delete mode 100644 gyp/resources.gyp create mode 100644 gyp/skia_launcher.gyp create mode 100644 platform_tools/android/gyp/skia_launcher.gypi create mode 100644 tools/timer/GpuTimer.cpp create mode 100644 tools/timer/GpuTimer.h create mode 100644 tools/timer/SysTimer_mach.cpp create mode 100644 tools/timer/SysTimer_mach.h create mode 100644 tools/timer/SysTimer_posix.cpp create mode 100644 tools/timer/SysTimer_posix.h create mode 100644 tools/timer/SysTimer_windows.cpp create mode 100644 tools/timer/SysTimer_windows.h create mode 100644 tools/timer/Timer.cpp create mode 100644 tools/timer/Timer.h create mode 100644 tools/timer/TimerData.cpp create mode 100644 tools/timer/TimerData.h diff --git a/bench/BenchGpuTimer_gl.cpp b/bench/BenchGpuTimer_gl.cpp deleted file mode 100644 index 349fc1529d..0000000000 --- a/bench/BenchGpuTimer_gl.cpp +++ /dev/null @@ -1,74 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include "BenchGpuTimer_gl.h" -#include "gl/SkGLContextHelper.h" -#include "gl/GrGLUtil.h" - -BenchGpuTimer::BenchGpuTimer(const SkGLContextHelper* glctx) { - fContext = glctx; - glctx->ref(); - glctx->makeCurrent(); - fStarted = false; - fSupported = GrGLGetVersion(glctx->gl()) > GR_GL_VER(3,3) || - glctx->hasExtension("GL_ARB_timer_query") || - glctx->hasExtension("GL_EXT_timer_query"); - - if (fSupported) { - SK_GL(*glctx, GenQueries(1, &fQuery)); - } -} - -BenchGpuTimer::~BenchGpuTimer() { - if (fSupported) { - fContext->makeCurrent(); - SK_GL(*fContext, DeleteQueries(1, &fQuery)); - } - fContext->unref(); -} - -void BenchGpuTimer::startGpu() { - if (fSupported) { - fContext->makeCurrent(); - fStarted = true; - SK_GL(*fContext, BeginQuery(GR_GL_TIME_ELAPSED, fQuery)); - } -} - -/** - * It is important to stop the cpu clocks first, - * as this will cpu wait for the gpu to finish. - */ -double BenchGpuTimer::endGpu() { - if (fSupported) { - fStarted = false; - fContext->makeCurrent(); - SK_GL(*fContext, EndQuery(GR_GL_TIME_ELAPSED)); - - GrGLint available = 0; - while (!available) { - SK_GL_NOERRCHECK(*fContext, GetQueryObjectiv(fQuery, - GR_GL_QUERY_RESULT_AVAILABLE, - &available)); - // If GetQueryObjectiv is erroring out we need some alternative - // means of breaking out of this loop - GrGLenum error; - SK_GL_RET_NOERRCHECK(*fContext, error, GetError()); - if (GR_GL_NO_ERROR != error) { - break; - } - } - GrGLuint64 totalGPUTimeElapsed = 0; - SK_GL(*fContext, GetQueryObjectui64v(fQuery, - GR_GL_QUERY_RESULT, - &totalGPUTimeElapsed)); - - return totalGPUTimeElapsed / 1000000.0; - } else { - return 0; - } -} diff --git a/bench/BenchGpuTimer_gl.h b/bench/BenchGpuTimer_gl.h deleted file mode 100644 index e472a4c514..0000000000 --- a/bench/BenchGpuTimer_gl.h +++ /dev/null @@ -1,26 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef SkBenchGpuTimer_DEFINED -#define SkBenchGpuTimer_DEFINED - -class SkGLContextHelper; - -class BenchGpuTimer { -public: - BenchGpuTimer(const SkGLContextHelper* glctx); - ~BenchGpuTimer(); - void startGpu(); - double endGpu(); -private: - unsigned fQuery; - int fStarted; - const SkGLContextHelper* fContext; - bool fSupported; -}; - -#endif diff --git a/bench/BenchSysTimer_c.cpp b/bench/BenchSysTimer_c.cpp deleted file mode 100644 index f4cbd39d73..0000000000 --- a/bench/BenchSysTimer_c.cpp +++ /dev/null @@ -1,27 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include "BenchSysTimer_c.h" - -//Time -#include - -void BenchSysTimer::startWall() { - this->fStartWall = time(); -} -void BenchSysTimer::startCpu() { - this->fStartCpu = clock(); -} - -double BenchSysTimer::endCpu() { - clock_t end_cpu = clock(); - this->fCpu = (end_cpu - this->fStartCpu) * CLOCKS_PER_SEC / 1000.0; -} -double BenchSysTimer::endWall() { - time_t end_wall = time(); - this->fWall = difftime(end_wall, this->fstartWall) / 1000.0; -} diff --git a/bench/BenchSysTimer_c.h b/bench/BenchSysTimer_c.h deleted file mode 100644 index 586f0b4ff0..0000000000 --- a/bench/BenchSysTimer_c.h +++ /dev/null @@ -1,26 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef SkBenchSysTimer_DEFINED -#define SkBenchSysTimer_DEFINED - -//Time -#include - -// Beware: this timer uses standard (as opposed to high precision) clocks -class BenchSysTimer { -public: - void startWall(); - void startCpu(); - double endCpu(); - double endWall(); -private: - clock_t start_cpu; - time_t fStartWall; -}; - -#endif diff --git a/bench/BenchSysTimer_mach.cpp b/bench/BenchSysTimer_mach.cpp deleted file mode 100644 index 1f0a6b9861..0000000000 --- a/bench/BenchSysTimer_mach.cpp +++ /dev/null @@ -1,76 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include "BenchSysTimer_mach.h" - -//Time -#include -#include - -static time_value_t macCpuTime() { - mach_port_t task = mach_task_self(); - if (task == MACH_PORT_NULL) { - time_value_t none = {0, 0}; - return none; - } - - task_thread_times_info thread_info_data; - mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT; - if (KERN_SUCCESS != task_info(task, - TASK_THREAD_TIMES_INFO, - reinterpret_cast(&thread_info_data), - &thread_info_count)) - { - time_value_t none = {0, 0}; - return none; - } - - time_value_add(&thread_info_data.user_time, &thread_info_data.system_time) - return thread_info_data.user_time; -} - -static double intervalInMSec(const time_value_t start_clock - , const time_value_t end_clock) -{ - double duration_clock; - if ((end_clock.microseconds - start_clock.microseconds) < 0) { - duration_clock = (end_clock.seconds - start_clock.seconds-1)*1000; - duration_clock += (1000000 - + end_clock.microseconds - - start_clock.microseconds) / 1000.0; - } else { - duration_clock = (end_clock.seconds - start_clock.seconds)*1000; - duration_clock += (end_clock.microseconds - start_clock.microseconds) - / 1000.0; - } - return duration_clock; -} - -void BenchSysTimer::startWall() { - this->fStartWall = mach_absolute_time(); -} -void BenchSysTimer::startCpu() { - this->fStartCpu = macCpuTime(); -} - -double BenchSysTimer::endCpu() { - time_value_t end_cpu = macCpuTime(); - return intervalInMSec(this->fStartCpu, end_cpu); -} -double BenchSysTimer::endWall() { - uint64_t end_wall = mach_absolute_time(); - - uint64_t elapsed = end_wall - this->fStartWall; - mach_timebase_info_data_t sTimebaseInfo; - if (KERN_SUCCESS != mach_timebase_info(&sTimebaseInfo)) { - return 0; - } else { - uint64_t elapsedNano = elapsed * sTimebaseInfo.numer - / sTimebaseInfo.denom; - return elapsedNano / 1000000.0; - } -} diff --git a/bench/BenchSysTimer_mach.h b/bench/BenchSysTimer_mach.h deleted file mode 100644 index 44d0e5eb49..0000000000 --- a/bench/BenchSysTimer_mach.h +++ /dev/null @@ -1,26 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef SkBenchSysTimer_DEFINED -#define SkBenchSysTimer_DEFINED - -//Time -#include -#include - -class BenchSysTimer { -public: - void startWall(); - void startCpu(); - double endCpu(); - double endWall(); -private: - time_value_t fStartCpu; - uint64_t fStartWall; -}; - -#endif diff --git a/bench/BenchSysTimer_posix.cpp b/bench/BenchSysTimer_posix.cpp deleted file mode 100644 index e6767e5af2..0000000000 --- a/bench/BenchSysTimer_posix.cpp +++ /dev/null @@ -1,57 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include "BenchSysTimer_posix.h" - -//Time -#include - -static double intervalInMSec(const timespec start_clock - , const timespec end_clock) -{ - double duration_clock; - if ((end_clock.tv_nsec - start_clock.tv_nsec) < 0) { - duration_clock = (end_clock.tv_sec - start_clock.tv_sec-1)*1000; - duration_clock += (1000000000 + end_clock.tv_nsec - start_clock.tv_nsec) - / 1000000.0; - } else { - duration_clock = (end_clock.tv_sec - start_clock.tv_sec)*1000; - duration_clock += (end_clock.tv_nsec - start_clock.tv_nsec) / 1000000.0; - } - return duration_clock; -} - -void BenchSysTimer::startWall() { - if (-1 == clock_gettime(CLOCK_MONOTONIC, &this->fWall)) { - timespec none = {0, 0}; - this->fWall = none; - } -} -void BenchSysTimer::startCpu() { - if (-1 == clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &this->fCpu)) { - timespec none = {0, 0}; - this->fCpu = none; - } -} - -double BenchSysTimer::endCpu() { - timespec end_cpu; - if (-1 == clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_cpu)) { - timespec none = {0, 0}; - end_cpu = none; - } - return intervalInMSec(this->fCpu, end_cpu); -} - -double BenchSysTimer::endWall() { - timespec end_wall; - if (-1 == clock_gettime(CLOCK_MONOTONIC, &end_wall)) { - timespec none = {0, 0}; - end_wall = none; - } - return intervalInMSec(this->fWall, end_wall); -} diff --git a/bench/BenchSysTimer_posix.h b/bench/BenchSysTimer_posix.h deleted file mode 100644 index 8fd97061b6..0000000000 --- a/bench/BenchSysTimer_posix.h +++ /dev/null @@ -1,25 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef SkBenchSysTimer_DEFINED -#define SkBenchSysTimer_DEFINED - -//Time -#include - -class BenchSysTimer { -public: - void startWall(); - void startCpu(); - double endCpu(); - double endWall(); -private: - timespec fCpu; - timespec fWall; -}; - -#endif diff --git a/bench/BenchSysTimer_windows.cpp b/bench/BenchSysTimer_windows.cpp deleted file mode 100644 index fab657a8c3..0000000000 --- a/bench/BenchSysTimer_windows.cpp +++ /dev/null @@ -1,64 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include "BenchSysTimer_windows.h" - -//Time -#define WIN32_LEAN_AND_MEAN 1 -#include - -static ULONGLONG winCpuTime() { - FILETIME createTime; - FILETIME exitTime; - FILETIME usrTime; - FILETIME sysTime; - if (0 == GetProcessTimes(GetCurrentProcess() - , &createTime, &exitTime - , &sysTime, &usrTime)) - { - return 0; - } - ULARGE_INTEGER start_cpu_sys; - ULARGE_INTEGER start_cpu_usr; - start_cpu_sys.LowPart = sysTime.dwLowDateTime; - start_cpu_sys.HighPart = sysTime.dwHighDateTime; - start_cpu_usr.LowPart = usrTime.dwLowDateTime; - start_cpu_usr.HighPart = usrTime.dwHighDateTime; - return start_cpu_sys.QuadPart + start_cpu_usr.QuadPart; -} - -void BenchSysTimer::startWall() { - if (0 == ::QueryPerformanceCounter(&this->fStartWall)) { - this->fStartWall.QuadPart = 0; - } -} -void BenchSysTimer::startCpu() { - this->fStartCpu = winCpuTime(); -} - -double BenchSysTimer::endCpu() { - ULONGLONG end_cpu = winCpuTime(); - return static_cast((end_cpu - this->fStartCpu)) / 10000.0L; -} -double BenchSysTimer::endWall() { - LARGE_INTEGER end_wall; - if (0 == ::QueryPerformanceCounter(&end_wall)) { - end_wall.QuadPart = 0; - } - - LARGE_INTEGER ticks_elapsed; - ticks_elapsed.QuadPart = end_wall.QuadPart - this->fStartWall.QuadPart; - - LARGE_INTEGER frequency; - if (0 == ::QueryPerformanceFrequency(&frequency)) { - return 0.0L; - } else { - return static_cast(ticks_elapsed.QuadPart) - / static_cast(frequency.QuadPart) - * 1000.0L; - } -} diff --git a/bench/BenchSysTimer_windows.h b/bench/BenchSysTimer_windows.h deleted file mode 100644 index 469332e4ed..0000000000 --- a/bench/BenchSysTimer_windows.h +++ /dev/null @@ -1,26 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef SkBenchSysTimer_DEFINED -#define SkBenchSysTimer_DEFINED - -//Time -#define WIN32_LEAN_AND_MEAN 1 -#include - -class BenchSysTimer { -public: - void startWall(); - void startCpu(); - double endCpu(); - double endWall(); -private: - ULONGLONG fStartCpu; - LARGE_INTEGER fStartWall; -}; - -#endif diff --git a/bench/BenchTimer.cpp b/bench/BenchTimer.cpp deleted file mode 100644 index f3e8e3b0ec..0000000000 --- a/bench/BenchTimer.cpp +++ /dev/null @@ -1,94 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include "BenchTimer.h" -#if defined(SK_BUILD_FOR_WIN32) - #include "BenchSysTimer_windows.h" -#elif defined(SK_BUILD_FOR_MAC) - #include "BenchSysTimer_mach.h" -#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) - #include "BenchSysTimer_posix.h" -#else - #include "BenchSysTimer_c.h" -#endif - -#if SK_SUPPORT_GPU -#include "BenchGpuTimer_gl.h" -#endif - -BenchTimer::BenchTimer(SkGLContextHelper* gl) - : fCpu(-1.0) - , fWall(-1.0) - , fTruncatedCpu(-1.0) - , fTruncatedWall(-1.0) - , fGpu(-1.0) -{ - fSysTimer = new BenchSysTimer(); - fTruncatedSysTimer = new BenchSysTimer(); -#if SK_SUPPORT_GPU - if (gl) { - fGpuTimer = new BenchGpuTimer(gl); - } else { - fGpuTimer = NULL; - } -#endif -} - -BenchTimer::~BenchTimer() { - delete fSysTimer; - delete fTruncatedSysTimer; -#if SK_SUPPORT_GPU - delete fGpuTimer; -#endif -} - -void BenchTimer::start(double durationScale) { - fDurationScale = durationScale; - - fSysTimer->startWall(); - fTruncatedSysTimer->startWall(); -#if SK_SUPPORT_GPU - if (fGpuTimer) { - fGpuTimer->startGpu(); - } -#endif - fSysTimer->startCpu(); - fTruncatedSysTimer->startCpu(); -} - -void BenchTimer::end() { - fCpu = fSysTimer->endCpu() * fDurationScale; -#if SK_SUPPORT_GPU - //It is important to stop the cpu clocks first, - //as the following will cpu wait for the gpu to finish. - if (fGpuTimer) { - fGpu = fGpuTimer->endGpu() * fDurationScale; - } -#endif - fWall = fSysTimer->endWall() * fDurationScale; -} - -void BenchTimer::truncatedEnd() { - fTruncatedCpu = fTruncatedSysTimer->endCpu() * fDurationScale; - fTruncatedWall = fTruncatedSysTimer->endWall() * fDurationScale; -} - -WallTimer::WallTimer() : fWall(-1.0), fSysTimer(new BenchSysTimer) {} - -WallTimer::~WallTimer() { - delete fSysTimer; -} - -void WallTimer::start(double durationScale) { - fDurationScale = durationScale; - fSysTimer->startWall(); -} - -void WallTimer::end() { - fWall = fSysTimer->endWall() * fDurationScale; -} - diff --git a/bench/BenchTimer.h b/bench/BenchTimer.h deleted file mode 100644 index 2abf10b80f..0000000000 --- a/bench/BenchTimer.h +++ /dev/null @@ -1,67 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef SkBenchTimer_DEFINED -#define SkBenchTimer_DEFINED - -#include - - -class BenchSysTimer; -class BenchGpuTimer; - -class SkGLContextHelper; - -/** - * SysTimers and GpuTimers are implemented orthogonally. - * This class combines 2 SysTimers and a GpuTimer into one single, - * platform specific Timer with a simple interface. The truncated - * timer doesn't include the time required for the GPU to finish - * its rendering. It should always be <= the un-truncated system - * times and (for GPU configurations) can be used to roughly (very - * roughly) gauge the GPU load/backlog. - */ -class BenchTimer { -public: - BenchTimer(SkGLContextHelper* gl = NULL); - ~BenchTimer(); - void start(double durationScale = 1); - void end(); - void truncatedEnd(); - double fCpu; - double fWall; - double fTruncatedCpu; - double fTruncatedWall; - double fGpu; - -private: - BenchSysTimer* fSysTimer; - BenchSysTimer* fTruncatedSysTimer; -#if SK_SUPPORT_GPU - BenchGpuTimer* fGpuTimer; -#endif - double fDurationScale; // for this start/end session -}; - -// Same as BenchTimer above, supporting only fWall but with much lower overhead. -// (Typically, ~30ns instead of BenchTimer's ~1us.) -class WallTimer { -public: - WallTimer(); - ~WallTimer(); - - void start(double durationScale = 1); - void end(); - - double fWall; - -private: - BenchSysTimer* fSysTimer; - double fDurationScale; -}; - -#endif diff --git a/bench/TimerData.cpp b/bench/TimerData.cpp deleted file mode 100644 index 0cb000280b..0000000000 --- a/bench/TimerData.cpp +++ /dev/null @@ -1,224 +0,0 @@ - -/* - * Copyright 2012 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include "TimerData.h" - -#include "BenchTimer.h" -#include - -using namespace std; - -TimerData::TimerData(int maxNumTimings) -: fMaxNumTimings(maxNumTimings) -, fCurrTiming(0) -, fWallTimes(maxNumTimings) -, fTruncatedWallTimes(maxNumTimings) -, fCpuTimes(maxNumTimings) -, fTruncatedCpuTimes(maxNumTimings) -, fGpuTimes(maxNumTimings){ -} - -bool TimerData::appendTimes(BenchTimer* timer) { - SkASSERT(timer != NULL); - if (fCurrTiming >= fMaxNumTimings) { - return false; - } - - fWallTimes[fCurrTiming] = timer->fWall; - fTruncatedWallTimes[fCurrTiming] = timer->fTruncatedWall; - fCpuTimes[fCurrTiming] = timer->fCpu; - fTruncatedCpuTimes[fCurrTiming] = timer->fTruncatedCpu; - fGpuTimes[fCurrTiming] = timer->fGpu; - - ++fCurrTiming; - - return true; -} - -SkString TimerData::getResult(const char* doubleFormat, - Result result, - const char *configName, - uint32_t timerFlags, - int itersPerTiming) { - SkASSERT(itersPerTiming >= 1); - - if (!fCurrTiming) { - return SkString(""); - } - - int numTimings = fCurrTiming; - - SkString wallStr(" msecs = "); - SkString truncWallStr(" Wmsecs = "); - SkString cpuStr(" cmsecs = "); - SkString truncCpuStr(" Cmsecs = "); - SkString gpuStr(" gmsecs = "); - - double wallMin = std::numeric_limits::max(); - double truncWallMin = std::numeric_limits::max(); - double cpuMin = std::numeric_limits::max(); - double truncCpuMin = std::numeric_limits::max(); - double gpuMin = std::numeric_limits::max(); - - double wallSum = 0; - double truncWallSum = 0; - double cpuSum = 0; - double truncCpuSum = 0; - double gpuSum = 0; - - for (int i = 0; i < numTimings; ++i) { - if (kPerIter_Result == result) { - wallStr.appendf(doubleFormat, fWallTimes[i] / itersPerTiming); - truncWallStr.appendf(doubleFormat, fTruncatedWallTimes[i] / itersPerTiming); - cpuStr.appendf(doubleFormat, fCpuTimes[i] / itersPerTiming); - truncCpuStr.appendf(doubleFormat, fTruncatedCpuTimes[i] / itersPerTiming); - gpuStr.appendf(doubleFormat, fGpuTimes[i] / itersPerTiming); - - if (i != numTimings - 1) { - static const char kSep[] = ", "; - wallStr.append(kSep); - truncWallStr.append(kSep); - cpuStr.append(kSep); - truncCpuStr.append(kSep); - gpuStr.append(kSep); - } - } else if (kMin_Result == result) { - wallMin = SkTMin(wallMin, fWallTimes[i]); - truncWallMin = SkTMin(truncWallMin, fTruncatedWallTimes[i]); - cpuMin = SkTMin(cpuMin, fCpuTimes[i]); - truncCpuMin = SkTMin(truncCpuMin, fTruncatedCpuTimes[i]); - gpuMin = SkTMin(gpuMin, fGpuTimes[i]); - } else { - SkASSERT(kAvg_Result == result); - wallSum += fWallTimes[i]; - truncWallSum += fTruncatedWallTimes[i]; - cpuSum += fCpuTimes[i]; - truncCpuSum += fTruncatedCpuTimes[i]; - } - - // We always track the GPU sum because whether it is non-zero indicates if valid gpu times - // were recorded at all. - gpuSum += fGpuTimes[i]; - } - - if (kMin_Result == result) { - wallStr.appendf(doubleFormat, wallMin / itersPerTiming); - truncWallStr.appendf(doubleFormat, truncWallMin / itersPerTiming); - cpuStr.appendf(doubleFormat, cpuMin / itersPerTiming); - truncCpuStr.appendf(doubleFormat, truncCpuMin / itersPerTiming); - gpuStr.appendf(doubleFormat, gpuMin / itersPerTiming); - } else if (kAvg_Result == result) { - int divisor = numTimings * itersPerTiming; - wallStr.appendf(doubleFormat, wallSum / divisor); - truncWallStr.appendf(doubleFormat, truncWallSum / divisor); - cpuStr.appendf(doubleFormat, cpuSum / divisor); - truncCpuStr.appendf(doubleFormat, truncCpuSum / divisor); - gpuStr.appendf(doubleFormat, gpuSum / divisor); - } - - SkString str; - str.printf(" %4s:", configName); - if (timerFlags & kWall_Flag) { - str += wallStr; - } - if (timerFlags & kTruncatedWall_Flag) { - str += truncWallStr; - } - if (timerFlags & kCpu_Flag) { - str += cpuStr; - } - if (timerFlags & kTruncatedCpu_Flag) { - str += truncCpuStr; - } - if ((timerFlags & kGpu_Flag) && gpuSum > 0) { - str += gpuStr; - } - return str; -} - -Json::Value TimerData::getJSON(uint32_t timerFlags, - Result result, - int itersPerTiming) { - SkASSERT(itersPerTiming >= 1); - Json::Value dataNode; - Json::Value wallNode, truncWall, cpuNode, truncCpu, gpuNode; - if (!fCurrTiming) { - return dataNode; - } - - int numTimings = fCurrTiming; - - double wallMin = std::numeric_limits::max(); - double truncWallMin = std::numeric_limits::max(); - double cpuMin = std::numeric_limits::max(); - double truncCpuMin = std::numeric_limits::max(); - double gpuMin = std::numeric_limits::max(); - - double wallSum = 0; - double truncWallSum = 0; - double cpuSum = 0; - double truncCpuSum = 0; - double gpuSum = 0; - - for (int i = 0; i < numTimings; ++i) { - if (kPerIter_Result == result) { - wallNode.append(fWallTimes[i] / itersPerTiming); - truncWall.append(fTruncatedWallTimes[i] / itersPerTiming); - cpuNode.append(fCpuTimes[i] / itersPerTiming); - truncCpu.append(fTruncatedCpuTimes[i] / itersPerTiming); - gpuNode.append(fGpuTimes[i] / itersPerTiming); - } else if (kMin_Result == result) { - wallMin = SkTMin(wallMin, fWallTimes[i]); - truncWallMin = SkTMin(truncWallMin, fTruncatedWallTimes[i]); - cpuMin = SkTMin(cpuMin, fCpuTimes[i]); - truncCpuMin = SkTMin(truncCpuMin, fTruncatedCpuTimes[i]); - gpuMin = SkTMin(gpuMin, fGpuTimes[i]); - } else { - SkASSERT(kAvg_Result == result); - wallSum += fWallTimes[i]; - truncWallSum += fTruncatedWallTimes[i]; - cpuSum += fCpuTimes[i]; - truncCpuSum += fTruncatedCpuTimes[i]; - } - - // We always track the GPU sum because whether it is non-zero indicates if valid gpu times - // were recorded at all. - gpuSum += fGpuTimes[i]; - } - - if (kMin_Result == result) { - wallNode.append(wallMin / itersPerTiming); - truncWall.append(truncWallMin / itersPerTiming); - cpuNode.append(cpuMin / itersPerTiming); - truncCpu.append(truncCpuMin / itersPerTiming); - gpuNode.append(gpuMin / itersPerTiming); - } else if (kAvg_Result == result) { - int divisor = numTimings * itersPerTiming; - wallNode.append(wallSum / divisor); - truncWall.append(truncWallSum / divisor); - cpuNode.append(cpuSum / divisor); - truncCpu.append(truncCpuSum / divisor); - gpuNode.append(gpuSum / divisor); - } - - if (timerFlags & kWall_Flag) { - dataNode["wall"] = wallNode; - } - if (timerFlags & kTruncatedWall_Flag) { - dataNode["truncWall"] = truncWall; - } - if (timerFlags & kCpu_Flag) { - dataNode["cpu"] = cpuNode; - } - if (timerFlags & kTruncatedCpu_Flag) { - dataNode["trucCpu"] = truncCpu; - } - if ((timerFlags & kGpu_Flag) && gpuSum > 0) { - dataNode["gpu"] = gpuNode; - } - return dataNode; -} diff --git a/bench/TimerData.h b/bench/TimerData.h deleted file mode 100644 index fb84df1a9e..0000000000 --- a/bench/TimerData.h +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright 2012 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef TimerData_DEFINED -#define TimerData_DEFINED - -#include "SkString.h" -#include "SkTemplates.h" - -#ifdef SK_BUILD_FOR_WIN - #pragma warning(push) - #pragma warning(disable : 4530) -#endif - -#include "SkJSONCPP.h" - -#ifdef SK_BUILD_FOR_WIN - #pragma warning(pop) -#endif - -class BenchTimer; - -class TimerData { -public: - /** - * Constructs a TimerData to hold at most maxNumTimings sets of elapsed timer values. - **/ - explicit TimerData(int maxNumTimings); - - /** - * Collect times from the BenchTimer for an iteration. It will fail if called more often than - * indicated in the constructor. - * - * @param BenchTimer Must not be null. - */ - bool appendTimes(BenchTimer*); - - enum Result { - kMin_Result, - kAvg_Result, - kPerIter_Result - }; - - enum TimerFlags { - kWall_Flag = 0x1, - kTruncatedWall_Flag = 0x2, - kCpu_Flag = 0x4, - kTruncatedCpu_Flag = 0x8, - kGpu_Flag = 0x10 - }; - - /** - * Gets the timer data results as a string. - * @param doubleFormat printf-style format for doubles (e.g. "%02d") - * @param result the type of result desired - * @param the name of the config being timed (prepended to results string) - * @param timerFlags bitfield of TimerFlags values indicating which timers should be reported. - * @param itersPerTiming the number of test/bench iterations that correspond to each - * appendTimes() call, 1 when appendTimes is called for each iteration. - */ - SkString getResult(const char* doubleFormat, - Result result, - const char* configName, - uint32_t timerFlags, - int itersPerTiming = 1); - Json::Value getJSON(uint32_t timerFlags, - Result result, - int itersPerTiming = 1); - -private: - int fMaxNumTimings; - int fCurrTiming; - - SkAutoTArray fWallTimes; - SkAutoTArray fTruncatedWallTimes; - SkAutoTArray fCpuTimes; - SkAutoTArray fTruncatedCpuTimes; - SkAutoTArray fGpuTimes; -}; - -#endif // TimerData_DEFINED diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp index 6b3f5872f2..5c3b7901af 100644 --- a/bench/benchmain.cpp +++ b/bench/benchmain.cpp @@ -6,7 +6,6 @@ */ #include "BenchLogger.h" -#include "BenchTimer.h" #include "Benchmark.h" #include "CrashHandler.h" #include "GMBench.h" @@ -24,6 +23,7 @@ #include "SkPictureRecorder.h" #include "SkString.h" #include "SkSurface.h" +#include "Timer.h" #if SK_SUPPORT_GPU #include "GrContext.h" @@ -530,9 +530,9 @@ int tool_main(int argc, char** argv) { if (Benchmark::kGPU_Backend == config.backend) { contextHelper = gContextFactory.getGLContext(config.contextType); } - BenchTimer timer(contextHelper); + Timer timer(contextHelper); #else - BenchTimer timer; + Timer timer; #endif double previous = std::numeric_limits::infinity(); diff --git a/debugger/QT/SkDebuggerGUI.cpp b/debugger/QT/SkDebuggerGUI.cpp index 1873afca67..5cecba273c 100644 --- a/debugger/QT/SkDebuggerGUI.cpp +++ b/debugger/QT/SkDebuggerGUI.cpp @@ -17,13 +17,13 @@ __SK_FORCE_IMAGE_DECODER_LINKING; #if defined(SK_BUILD_FOR_WIN32) - #include "BenchSysTimer_windows.h" + #include "SysTimer_windows.h" #elif defined(SK_BUILD_FOR_MAC) - #include "BenchSysTimer_mach.h" + #include "SysTimer_mach.h" #elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) - #include "BenchSysTimer_posix.h" + #include "SysTimer_posix.h" #else - #include "BenchSysTimer_c.h" + #include "SysTimer_c.h" #endif @@ -202,7 +202,7 @@ public: double totTime() const { return fTot; } protected: - BenchSysTimer fTimer; + SysTimer fTimer; SkTDArray fSkipCommands; // has the command been deleted in the GUI? SkTDArray fTimes; // sum of time consumed for each command SkTDArray fTypeTimes; // sum of time consumed for each type of command (e.g., drawPath) diff --git a/gyp/SampleApp.gyp b/gyp/SampleApp.gyp index abfc8b77f9..9ced81b98f 100644 --- a/gyp/SampleApp.gyp +++ b/gyp/SampleApp.gyp @@ -150,8 +150,8 @@ 'flags.gyp:flags', 'lua.gyp:lua', 'pdf.gyp:pdf', - 'resources.gyp:resources', 'skia_lib.gyp:skia_lib', + 'tools.gyp:resources', 'views.gyp:views', 'views_animated.gyp:views_animated', 'xml.gyp:xml', diff --git a/gyp/apptype_console.gypi b/gyp/apptype_console.gypi index cde87792c7..b9939987b8 100644 --- a/gyp/apptype_console.gypi +++ b/gyp/apptype_console.gypi @@ -15,7 +15,7 @@ [ 'skia_os == "android" and not skia_android_framework', { 'dependencies': [ 'android_deps.gyp:Android_EntryPoint', - 'android_system.gyp:skia_launcher', + 'skia_launcher.gyp:skia_launcher', ], }], [ 'skia_os == "nacl"', { diff --git a/gyp/bench.gyp b/gyp/bench.gyp index 15927e6413..1c1943705f 100644 --- a/gyp/bench.gyp +++ b/gyp/bench.gyp @@ -9,13 +9,13 @@ 'target_name': 'bench', 'type': 'executable', 'dependencies': [ - 'bench_timer', - 'crash_handler.gyp:CrashHandler', 'etc1.gyp:libetc1', 'flags.gyp:flags', 'jsoncpp.gyp:jsoncpp', - 'resources.gyp:resources', 'skia_lib.gyp:skia_lib', + 'tools.gyp:crash_handler', + 'tools.gyp:resources', + 'tools.gyp:timer', ], 'sources': [ '../bench/BenchLogger.cpp', @@ -50,63 +50,5 @@ 'gmslides.gypi', ], }, - { - 'target_name' : 'bench_timer', - 'type': 'static_library', - 'sources': [ - '../bench/BenchTimer.h', - '../bench/BenchTimer.cpp', - '../bench/BenchSysTimer_mach.h', - '../bench/BenchSysTimer_mach.cpp', - '../bench/BenchSysTimer_posix.h', - '../bench/BenchSysTimer_posix.cpp', - '../bench/BenchSysTimer_windows.h', - '../bench/BenchSysTimer_windows.cpp', - ], - 'include_dirs': [ - '../src/core', - '../src/gpu', - '../tools', - ], - 'direct_dependent_settings': { - 'include_dirs': ['../bench'], - }, - 'dependencies': [ - 'skia_lib.gyp:skia_lib', - ], - 'conditions': [ - [ 'skia_os not in ["mac", "ios"]', { - 'sources!': [ - '../bench/BenchSysTimer_mach.h', - '../bench/BenchSysTimer_mach.cpp', - ], - }], - [ 'skia_os not in ["linux", "freebsd", "openbsd", "solaris", "android", "chromeos"]', { - 'sources!': [ - '../bench/BenchSysTimer_posix.h', - '../bench/BenchSysTimer_posix.cpp', - ], - }], - [ 'skia_os in ["linux", "freebsd", "openbsd", "solaris", "chromeos"]', { - 'link_settings': { - 'libraries': [ - '-lrt', - ], - }, - }], - [ 'skia_os != "win"', { - 'sources!': [ - '../bench/BenchSysTimer_windows.h', - '../bench/BenchSysTimer_windows.cpp', - ], - }], - ['skia_gpu == 1', { - 'sources': [ - '../bench/BenchGpuTimer_gl.h', - '../bench/BenchGpuTimer_gl.cpp', - ], - }], - ], - } ], } diff --git a/gyp/crash_handler.gyp b/gyp/crash_handler.gyp deleted file mode 100644 index 7e3599c8d9..0000000000 --- a/gyp/crash_handler.gyp +++ /dev/null @@ -1,18 +0,0 @@ -{ - 'targets': [{ - 'target_name': 'CrashHandler', - 'type': 'static_library', - 'sources': [ '../tools/CrashHandler.cpp' ], - 'dependencies': [ 'skia_lib.gyp:skia_lib' ], - 'direct_dependent_settings': { - 'include_dirs': [ '../tools' ], - }, - 'all_dependent_settings': { - 'msvs_settings': { - 'VCLinkerTool': { - 'AdditionalDependencies': [ 'Dbghelp.lib' ], - } - }, - } - }] -} diff --git a/gyp/debugger.gyp b/gyp/debugger.gyp index 84f03972df..4add7439a8 100644 --- a/gyp/debugger.gyp +++ b/gyp/debugger.gyp @@ -96,8 +96,8 @@ ], 'dependencies': [ 'skia_lib.gyp:skia_lib', - 'bench.gyp:bench_timer', 'tools.gyp:picture_renderer', + 'tools.gyp:timer', ], 'conditions': [ [ 'skia_os == "nacl"', { diff --git a/gyp/dm.gyp b/gyp/dm.gyp index f69ffe5f4b..2d02796b45 100644 --- a/gyp/dm.gyp +++ b/gyp/dm.gyp @@ -55,12 +55,12 @@ '../src/utils/debugger/SkObjectParser.cpp', ], 'dependencies': [ - 'crash_handler.gyp:CrashHandler', 'etc1.gyp:libetc1', 'flags.gyp:flags', 'gputest.gyp:skgputest', 'jsoncpp.gyp:jsoncpp', 'skia_lib.gyp:skia_lib', + 'tools.gyp:crash_handler', ], 'conditions': [ ['skia_android_framework', { diff --git a/gyp/gm.gyp b/gyp/gm.gyp index 0b0054b701..fd56e7eebe 100644 --- a/gyp/gm.gyp +++ b/gyp/gm.gyp @@ -4,28 +4,6 @@ 'apptype_console.gypi', ], 'targets': [ - { - 'target_name': 'gm_expectations', - 'type': 'static_library', - 'include_dirs' : [ - '../src/utils/', - ], - 'sources': [ - '../gm/gm_expectations.h', - '../gm/gm_expectations.cpp', - '../tools/sk_tool_utils.cpp', - ], - 'dependencies': [ - 'crash_handler.gyp:CrashHandler', - 'jsoncpp.gyp:jsoncpp', - 'skia_lib.gyp:skia_lib', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '../gm/', - ], - }, - }, { 'target_name': 'gm', 'type': 'executable', @@ -49,11 +27,12 @@ 'dependencies': [ 'etc1.gyp:libetc1', 'flags.gyp:flags', - 'gm.gyp:gm_expectations', 'jsoncpp.gyp:jsoncpp', 'pdf.gyp:pdf', - 'resources.gyp:resources', 'skia_lib.gyp:skia_lib', + 'tools.gyp:crash_handler', + 'tools.gyp:gm_expectations', + 'tools.gyp:resources', ], 'conditions': [ ['skia_android_framework', { diff --git a/gyp/resources.gyp b/gyp/resources.gyp deleted file mode 100644 index 48e96c3cc5..0000000000 --- a/gyp/resources.gyp +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2014 Google Inc. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -{ - 'targets': [ - { - 'target_name': 'resources', - 'type': 'static_library', - 'sources': [ - '../tools/Resources.cpp', - '../tools/Resources.h', - ], - 'dependencies': [ - 'flags.gyp:flags', - 'skia_lib.gyp:skia_lib', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '../tools/', - ], - }, - }, - ] -} diff --git a/gyp/skia_launcher.gyp b/gyp/skia_launcher.gyp new file mode 100644 index 0000000000..d9970b4290 --- /dev/null +++ b/gyp/skia_launcher.gyp @@ -0,0 +1,3 @@ +{ + 'includes': [ '../platform_tools/android/gyp/skia_launcher.gypi' ] +} diff --git a/gyp/tests.gyp b/gyp/tests.gyp index 80768efa35..155207ed6f 100644 --- a/gyp/tests.gyp +++ b/gyp/tests.gyp @@ -11,7 +11,7 @@ 'pathops_unittest.gypi', 'tests.gypi', ], - 'dependencies': [ 'crash_handler.gyp:CrashHandler' ], + 'dependencies': [ 'tools.gyp:crash_handler' ], 'sources': [ '../tests/skia_test.cpp', ], diff --git a/gyp/tests.gypi b/gyp/tests.gypi index 2a7dddd4ff..f135107c34 100644 --- a/gyp/tests.gypi +++ b/gyp/tests.gypi @@ -20,9 +20,9 @@ 'experimental.gyp:experimental', 'flags.gyp:flags', 'pdf.gyp:pdf', - 'resources.gyp:resources', 'skia_lib.gyp:skia_lib', 'tools.gyp:picture_utils', + 'tools.gyp:resources', ], 'sources': [ '../tests/Test.cpp', diff --git a/gyp/tools.gyp b/gyp/tools.gyp index 5ea127296a..eeb210a497 100644 --- a/gyp/tools.gyp +++ b/gyp/tools.gyp @@ -43,6 +43,86 @@ ], ], }, + { # This would go in gm.gyp, but it's also used by skimage below. + 'target_name': 'gm_expectations', + 'type': 'static_library', + 'include_dirs' : [ '../src/utils/' ], + 'sources': [ + '../gm/gm_expectations.cpp', + '../tools/sk_tool_utils.cpp', + ], + 'dependencies': [ + 'jsoncpp.gyp:jsoncpp', + 'skia_lib.gyp:skia_lib', + ], + 'direct_dependent_settings': { + 'include_dirs': [ '../gm/' ], + }, + }, + { + 'target_name': 'crash_handler', + 'type': 'static_library', + 'sources': [ '../tools/CrashHandler.cpp' ], + 'dependencies': [ 'skia_lib.gyp:skia_lib' ], + 'direct_dependent_settings': { + 'include_dirs': [ '../tools' ], + }, + 'all_dependent_settings': { + 'msvs_settings': { + 'VCLinkerTool': { + 'AdditionalDependencies': [ 'Dbghelp.lib' ], + } + }, + } + }, + { + 'target_name': 'resources', + 'type': 'static_library', + 'sources': [ '../tools/Resources.cpp' ], + 'dependencies': [ + 'flags.gyp:flags', + 'skia_lib.gyp:skia_lib', + ], + 'direct_dependent_settings': { + 'include_dirs': [ '../tools/', ], + }, + }, + { + 'target_name' : 'timer', + 'type': 'static_library', + 'sources': [ + '../tools/timer/Timer.cpp', + '../tools/timer/TimerData.cpp', + ], + 'include_dirs': [ + '../src/core', + '../src/gpu', + ], + 'direct_dependent_settings': { + 'include_dirs': ['../tools/timer'], + }, + 'dependencies': [ + 'skia_lib.gyp:skia_lib', + 'jsoncpp.gyp:jsoncpp', + ], + 'conditions': [ + ['skia_gpu == 1', { + 'sources': [ '../tools/timer/GpuTimer.cpp' ], + }], + [ 'skia_os in ["mac", "ios"]', { + 'sources': [ '../tools/timer/SysTimer_mach.cpp' ], + }], + [ 'skia_os == "win"', { + 'sources': [ '../tools/timer/SysTimer_windows.cpp' ], + }], + [ 'skia_os in ["linux", "freebsd", "openbsd", "solaris", "android", "chromeos"]', { + 'sources': [ '../tools/timer/SysTimer_posix.cpp' ], + }], + [ 'skia_os in ["linux", "freebsd", "openbsd", "solaris", "chromeos"]', { + 'link_settings': { 'libraries': [ '-lrt' ] }, + }], + ], + }, { 'target_name': 'skdiff', 'type': 'executable', @@ -178,8 +258,8 @@ '../src/utils/', ], 'dependencies': [ + 'gm_expectations', 'flags.gyp:flags', - 'gm.gyp:gm_expectations', 'jsoncpp.gyp:jsoncpp', 'skia_lib.gyp:skia_lib', ], @@ -299,14 +379,13 @@ '../src/lazy/', ], 'dependencies': [ - 'bench.gyp:bench_timer', - 'crash_handler.gyp:CrashHandler', + 'timer', + 'crash_handler', 'flags.gyp:flags', 'jsoncpp.gyp:jsoncpp', 'skia_lib.gyp:skia_lib', 'tools.gyp:picture_renderer', 'tools.gyp:picture_utils', - 'tools.gyp:timer_data', ], }, { @@ -322,7 +401,7 @@ '../src/lazy', ], 'dependencies': [ - 'bench.gyp:bench_timer', + 'timer', 'flags.gyp:flags', 'skia_lib.gyp:skia_lib', ], @@ -338,7 +417,7 @@ '../src/images', ], 'dependencies': [ - 'bench.gyp:bench_timer', + 'timer', 'flags.gyp:flags', 'skia_lib.gyp:skia_lib', ], @@ -357,7 +436,7 @@ '../src/lazy', ], 'dependencies': [ - 'bench.gyp:bench_timer', + 'timer', 'flags.gyp:flags', 'skia_lib.gyp:skia_lib', ], @@ -505,9 +584,8 @@ # Bench code: ], 'dependencies': [ - 'bench.gyp:bench_timer', + 'timer', 'flags.gyp:flags', - 'tools.gyp:timer_data', 'skia_lib.gyp:skia_lib', 'tools.gyp:picture_renderer', 'tools.gyp:picture_utils', @@ -544,17 +622,6 @@ 'skia_lib.gyp:skia_lib', ], }, - { - 'target_name': 'timer_data', - 'type': 'static_library', - 'sources': [ - '../bench/TimerData.cpp', - ], - 'dependencies': [ - 'skia_lib.gyp:skia_lib', - 'jsoncpp.gyp:jsoncpp' - ] - } ], 'conditions': [ ['skia_shared_lib', diff --git a/platform_tools/android/gyp/skia_android.gypi b/platform_tools/android/gyp/skia_android.gypi index 9ebee7cc6d..624b599bd6 100644 --- a/platform_tools/android/gyp/skia_android.gypi +++ b/platform_tools/android/gyp/skia_android.gypi @@ -44,13 +44,6 @@ }, ], }, - { - 'target_name': 'skia_launcher', - 'type': 'executable', - 'sources': [ - '../launcher/skia_launcher.cpp', - ], - }, { 'target_name': 'SampleApp_APK', 'type': 'none', diff --git a/platform_tools/android/gyp/skia_launcher.gypi b/platform_tools/android/gyp/skia_launcher.gypi new file mode 100644 index 0000000000..f8b5dfd794 --- /dev/null +++ b/platform_tools/android/gyp/skia_launcher.gypi @@ -0,0 +1,7 @@ +{ + 'targets': [{ + 'target_name': 'skia_launcher', + 'type': 'executable', + 'sources': [ '../launcher/skia_launcher.cpp' ], + }] +} diff --git a/tools/DumpRecord.cpp b/tools/DumpRecord.cpp index 2376fb9cf0..6e679a5430 100644 --- a/tools/DumpRecord.cpp +++ b/tools/DumpRecord.cpp @@ -10,8 +10,8 @@ #include "SkRecord.h" #include "SkRecordDraw.h" -#include "BenchTimer.h" #include "DumpRecord.h" +#include "Timer.h" namespace { @@ -33,7 +33,7 @@ public: template void operator()(const T& command) { - BenchTimer timer; + Timer timer; timer.start(); fDraw(command); timer.end(); diff --git a/tools/PictureBenchmark.cpp b/tools/PictureBenchmark.cpp index 30967c7381..85a49f4e5e 100644 --- a/tools/PictureBenchmark.cpp +++ b/tools/PictureBenchmark.cpp @@ -5,7 +5,7 @@ * found in the LICENSE file. */ -#include "BenchTimer.h" +#include "Timer.h" #include "PictureBenchmark.h" #include "SkCanvas.h" #include "SkPicture.h" @@ -42,13 +42,13 @@ void PictureBenchmark::setTimersToShow(bool wall, fTimerTypes |= gpu ? TimerData::kGpu_Flag : 0; } -BenchTimer* PictureBenchmark::setupTimer(bool useGLTimer) { +Timer* PictureBenchmark::setupTimer(bool useGLTimer) { #if SK_SUPPORT_GPU if (useGLTimer && fRenderer != NULL && fRenderer->isUsingGpuDevice()) { - return SkNEW_ARGS(BenchTimer, (fRenderer->getGLContext())); + return SkNEW_ARGS(Timer, (fRenderer->getGLContext())); } #endif - return SkNEW_ARGS(BenchTimer, (NULL)); + return SkNEW_ARGS(Timer, (NULL)); } PictureRenderer* PictureBenchmark::setRenderer(sk_tools::PictureRenderer* renderer) { @@ -147,11 +147,11 @@ void PictureBenchmark::run(SkPicture* pict) { // seems to cause problems (i.e., INVALID_OPERATIONs) on several // platforms. To work around this, we disable the gpu timer on the // long running timer. - SkAutoTDelete longRunningTimer(this->setupTimer()); + SkAutoTDelete longRunningTimer(this->setupTimer()); TimerData longRunningTimerData(numOuterLoops); for (int outer = 0; outer < numOuterLoops; ++outer) { - SkAutoTDelete perTileTimer(this->setupTimer(false)); + SkAutoTDelete perTileTimer(this->setupTimer(false)); TimerData perTileTimerData(numInnerLoops); longRunningTimer->start(); @@ -201,11 +201,11 @@ void PictureBenchmark::run(SkPicture* pict) { numInnerLoops); } } else { - SkAutoTDelete longRunningTimer(this->setupTimer()); + SkAutoTDelete longRunningTimer(this->setupTimer()); TimerData longRunningTimerData(numOuterLoops); for (int outer = 0; outer < numOuterLoops; ++outer) { - SkAutoTDelete perRunTimer(this->setupTimer(false)); + SkAutoTDelete perRunTimer(this->setupTimer(false)); TimerData perRunTimerData(numInnerLoops); longRunningTimer->start(); diff --git a/tools/PictureBenchmark.h b/tools/PictureBenchmark.h index 142d52685e..1ddd18ea16 100644 --- a/tools/PictureBenchmark.h +++ b/tools/PictureBenchmark.h @@ -13,8 +13,8 @@ #include "SkTypes.h" #include "TimerData.h" -class BenchTimer; class SkPicture; +class Timer; namespace sk_tools { @@ -67,7 +67,7 @@ private: PictureResultsWriter* fWriter; - BenchTimer* setupTimer(bool useGLTimer = true); + Timer* setupTimer(bool useGLTimer = true); }; } diff --git a/tools/bbh_shootout.cpp b/tools/bbh_shootout.cpp index e657917aad..64fc6d87d8 100644 --- a/tools/bbh_shootout.cpp +++ b/tools/bbh_shootout.cpp @@ -5,7 +5,7 @@ * found in the LICENSE file. */ -#include "BenchTimer.h" +#include "Timer.h" #include "Benchmark.h" #include "LazyDecodeBitmap.h" #include "PictureBenchmark.h" @@ -64,7 +64,7 @@ static void do_benchmark_work(sk_tools::PictureRenderer* renderer, BBoxType bBoxType, SkPicture* pic, const int numRepeats, - BenchTimer* timer) { + Timer* timer) { renderer->setBBoxHierarchyType(bBoxType); renderer->setGridSize(FLAGS_tilesize, FLAGS_tilesize); renderer->init(pic, NULL, NULL, NULL, false); @@ -106,14 +106,14 @@ int tool_main(int argc, char** argv) { if (!includeBBoxType[bBoxType]) { continue; } if (FLAGS_playback > 0) { sk_tools::TiledPictureRenderer playbackRenderer; - BenchTimer playbackTimer; + Timer playbackTimer; do_benchmark_work(&playbackRenderer, (BBoxType)bBoxType, picture, FLAGS_playback, &playbackTimer); measurement.fPlaybackAverage[bBoxType] = playbackTimer.fCpu; } if (FLAGS_record > 0) { sk_tools::RecordPictureRenderer recordRenderer; - BenchTimer recordTimer; + Timer recordTimer; do_benchmark_work(&recordRenderer, (BBoxType)bBoxType, picture, FLAGS_record, &recordTimer); measurement.fRecordAverage[bBoxType] = recordTimer.fCpu; diff --git a/tools/bench_pictures_main.cpp b/tools/bench_pictures_main.cpp index d9b767b2aa..503269af6a 100644 --- a/tools/bench_pictures_main.cpp +++ b/tools/bench_pictures_main.cpp @@ -6,7 +6,7 @@ */ #include "BenchLogger.h" -#include "BenchTimer.h" +#include "Timer.h" #include "CopyTilesRenderer.h" #include "CrashHandler.h" #include "LazyDecodeBitmap.h" diff --git a/tools/bench_playback.cpp b/tools/bench_playback.cpp index 26fa1c7ee8..6ebe19d36f 100644 --- a/tools/bench_playback.cpp +++ b/tools/bench_playback.cpp @@ -16,10 +16,8 @@ #include "../include/record/SkRecording.h" -#include "BenchTimer.h" #include "Stats.h" - -typedef WallTimer Timer; +#include "Timer.h" __SK_FORCE_IMAGE_DECODER_LINKING; @@ -78,15 +76,16 @@ static void bench(SkPMColor* scratch, SkPicture& src, const char* name) { // Draw once to warm any caches. The first sample otherwise can be very noisy. draw(*record, *picture, canvas.get()); - Timer timer; + WallTimer timer; + const double scale = timescale(); SkAutoTMalloc samples(FLAGS_samples); for (int i = 0; i < FLAGS_samples; i++) { // We assume timer overhead (typically, ~30ns) is insignificant // compared to draw runtime (at least ~100us, usually several ms). - timer.start(timescale()); + timer.start(); draw(*record, *picture, canvas.get()); timer.end(); - samples[i] = timer.fWall; + samples[i] = timer.fWall * scale; } Stats stats(samples.get(), FLAGS_samples); diff --git a/tools/bench_record.cpp b/tools/bench_record.cpp index 0024c2ccdb..545731900b 100644 --- a/tools/bench_record.cpp +++ b/tools/bench_record.cpp @@ -14,11 +14,9 @@ #include "SkStream.h" #include "SkString.h" -#include "BenchTimer.h" #include "LazyDecodeBitmap.h" #include "Stats.h" - -typedef WallTimer Timer; +#include "Timer.h" __SK_FORCE_IMAGE_DECODER_LINKING; @@ -81,12 +79,13 @@ static void bench_record(const SkPicture& src, rerecord(src, bbhFactory); // Rerecord once to see how many times we should loop to make timer overhead insignificant. - Timer timer; + WallTimer timer; + const double scale = timescale(); do { - timer.start(timescale()); + timer.start(); rerecord(src, bbhFactory); timer.end(); - } while (timer.fWall < timerOverhead); // Loop just in case something bizarre happens. + } while (timer.fWall * scale < timerOverhead); // Loop just in case something bizarre happens. // We want (timer overhead / measurement) to be less than FLAGS_overheadGoal. // So in each sample, we'll loop enough times to have made that true for our first measurement. @@ -94,12 +93,12 @@ static void bench_record(const SkPicture& src, SkAutoTMalloc samples(FLAGS_samples); for (int i = 0; i < FLAGS_samples; i++) { - timer.start(timescale()); + timer.start(); for (int j = 0; j < loops; j++) { rerecord(src, bbhFactory); } timer.end(); - samples[i] = timer.fWall / loops; + samples[i] = timer.fWall * scale / loops; } Stats stats(samples.get(), FLAGS_samples); @@ -132,12 +131,13 @@ int tool_main(int argc, char** argv) { // Each run will use this timer overhead estimate to guess how many times it should run. static const int kOverheadLoops = 10000000; - Timer timer; + WallTimer timer; double overheadEstimate = 0.0; + const double scale = timescale(); for (int i = 0; i < kOverheadLoops; i++) { - timer.start(timescale()); + timer.start(); timer.end(); - overheadEstimate += timer.fWall; + overheadEstimate += timer.fWall * scale; } overheadEstimate /= kOverheadLoops; diff --git a/tools/skpdiff/skpdiff_util.cpp b/tools/skpdiff/skpdiff_util.cpp index 171721c3be..983bee20b3 100644 --- a/tools/skpdiff/skpdiff_util.cpp +++ b/tools/skpdiff/skpdiff_util.cpp @@ -83,7 +83,7 @@ const char* cl_error_to_string(cl_int err) { } #endif -// TODO refactor BenchTimer to be used here +// TODO refactor Timer to be used here double get_seconds() { #if SK_BUILD_FOR_WIN32 LARGE_INTEGER currentTime; diff --git a/tools/timer/GpuTimer.cpp b/tools/timer/GpuTimer.cpp new file mode 100644 index 0000000000..3174449f78 --- /dev/null +++ b/tools/timer/GpuTimer.cpp @@ -0,0 +1,74 @@ + +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "GpuTimer.h" +#include "gl/SkGLContextHelper.h" +#include "gl/GrGLUtil.h" + +GpuTimer::GpuTimer(const SkGLContextHelper* glctx) { + fContext = glctx; + glctx->ref(); + glctx->makeCurrent(); + fStarted = false; + fSupported = GrGLGetVersion(glctx->gl()) > GR_GL_VER(3,3) || + glctx->hasExtension("GL_ARB_timer_query") || + glctx->hasExtension("GL_EXT_timer_query"); + + if (fSupported) { + SK_GL(*glctx, GenQueries(1, &fQuery)); + } +} + +GpuTimer::~GpuTimer() { + if (fSupported) { + fContext->makeCurrent(); + SK_GL(*fContext, DeleteQueries(1, &fQuery)); + } + fContext->unref(); +} + +void GpuTimer::start() { + if (fSupported) { + fContext->makeCurrent(); + fStarted = true; + SK_GL(*fContext, BeginQuery(GR_GL_TIME_ELAPSED, fQuery)); + } +} + +/** + * It is important to stop the cpu clocks first, + * as this will cpu wait for the gpu to finish. + */ +double GpuTimer::end() { + if (fSupported) { + fStarted = false; + fContext->makeCurrent(); + SK_GL(*fContext, EndQuery(GR_GL_TIME_ELAPSED)); + + GrGLint available = 0; + while (!available) { + SK_GL_NOERRCHECK(*fContext, GetQueryObjectiv(fQuery, + GR_GL_QUERY_RESULT_AVAILABLE, + &available)); + // If GetQueryObjectiv is erroring out we need some alternative + // means of breaking out of this loop + GrGLenum error; + SK_GL_RET_NOERRCHECK(*fContext, error, GetError()); + if (GR_GL_NO_ERROR != error) { + break; + } + } + GrGLuint64 totalGPUTimeElapsed = 0; + SK_GL(*fContext, GetQueryObjectui64v(fQuery, + GR_GL_QUERY_RESULT, + &totalGPUTimeElapsed)); + + return totalGPUTimeElapsed / 1000000.0; + } else { + return 0; + } +} diff --git a/tools/timer/GpuTimer.h b/tools/timer/GpuTimer.h new file mode 100644 index 0000000000..2100312a21 --- /dev/null +++ b/tools/timer/GpuTimer.h @@ -0,0 +1,25 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef GpuTimer_DEFINED +#define GpuTimer_DEFINED + +class SkGLContextHelper; + +class GpuTimer { +public: + GpuTimer(const SkGLContextHelper*); + ~GpuTimer(); + void start(); + double end(); +private: + unsigned fQuery; + int fStarted; + const SkGLContextHelper* fContext; + bool fSupported; +}; + +#endif diff --git a/tools/timer/SysTimer_mach.cpp b/tools/timer/SysTimer_mach.cpp new file mode 100644 index 0000000000..aca12dee52 --- /dev/null +++ b/tools/timer/SysTimer_mach.cpp @@ -0,0 +1,66 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "SysTimer_mach.h" + +static time_value_t mac_cpu_time() { + mach_port_t task = mach_task_self(); + if (task == MACH_PORT_NULL) { + time_value_t none = {0, 0}; + return none; + } + + task_thread_times_info thread_info_data; + mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT; + if (KERN_SUCCESS != task_info(task, + TASK_THREAD_TIMES_INFO, + reinterpret_cast(&thread_info_data), + &thread_info_count)) { + time_value_t none = {0, 0}; + return none; + } + + time_value_add(&thread_info_data.user_time, &thread_info_data.system_time) + return thread_info_data.user_time; +} + +static double interval_in_ms(time_value_t start_clock, time_value_t end_clock) { + double duration_clock; + if ((end_clock.microseconds - start_clock.microseconds) < 0) { + duration_clock = (end_clock.seconds - start_clock.seconds-1) * 1000; + duration_clock += (1000000 + end_clock.microseconds - start_clock.microseconds) / 1000.0; + } else { + duration_clock = (end_clock.seconds - start_clock.seconds) * 1000; + duration_clock += (end_clock.microseconds - start_clock.microseconds) / 1000.0; + } + return duration_clock; +} + +void SysTimer::startWall() { + fStartWall = mach_absolute_time(); +} + +void SysTimer::startCpu() { + fStartCpu = mac_cpu_time(); +} + +double SysTimer::endCpu() { + time_value_t end_cpu = mac_cpu_time(); + return interval_in_ms(fStartCpu, end_cpu); +} + +double SysTimer::endWall() { + uint64_t end_wall = mach_absolute_time(); + + uint64_t elapsed = end_wall - fStartWall; + mach_timebase_info_data_t sTimebaseInfo; + if (KERN_SUCCESS != mach_timebase_info(&sTimebaseInfo)) { + return 0; + } else { + uint64_t elapsedNano = elapsed * sTimebaseInfo.numer / sTimebaseInfo.denom; + return elapsedNano / 1000000.0; + } +} diff --git a/tools/timer/SysTimer_mach.h b/tools/timer/SysTimer_mach.h new file mode 100644 index 0000000000..8c21d57b36 --- /dev/null +++ b/tools/timer/SysTimer_mach.h @@ -0,0 +1,24 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef SysTimer_DEFINED +#define SysTimer_DEFINED + +#include +#include + +class SysTimer { +public: + void startWall(); + void startCpu(); + double endCpu(); + double endWall(); +private: + time_value_t fStartCpu; + uint64_t fStartWall; +}; + +#endif diff --git a/tools/timer/SysTimer_posix.cpp b/tools/timer/SysTimer_posix.cpp new file mode 100644 index 0000000000..4b7d708aab --- /dev/null +++ b/tools/timer/SysTimer_posix.cpp @@ -0,0 +1,51 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "SysTimer_posix.h" + +static double interval_in_ms(timespec start_clock, timespec end_clock) +{ + double duration_clock; + if ((end_clock.tv_nsec - start_clock.tv_nsec) < 0) { + duration_clock = (end_clock.tv_sec - start_clock.tv_sec - 1) * 1000; + duration_clock += (1000000000 + end_clock.tv_nsec - start_clock.tv_nsec) / 1000000.0; + } else { + duration_clock = (end_clock.tv_sec - start_clock.tv_sec) * 1000; + duration_clock += (end_clock.tv_nsec - start_clock.tv_nsec) / 1000000.0; + } + return duration_clock; +} + +void SysTimer::startWall() { + if (-1 == clock_gettime(CLOCK_MONOTONIC, &fWall)) { + timespec none = {0, 0}; + fWall = none; + } +} +void SysTimer::startCpu() { + if (-1 == clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &fCpu)) { + timespec none = {0, 0}; + fCpu = none; + } +} + +double SysTimer::endCpu() { + timespec end_cpu; + if (-1 == clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_cpu)) { + timespec none = {0, 0}; + end_cpu = none; + } + return interval_in_ms(fCpu, end_cpu); +} + +double SysTimer::endWall() { + timespec end_wall; + if (-1 == clock_gettime(CLOCK_MONOTONIC, &end_wall)) { + timespec none = {0, 0}; + end_wall = none; + } + return interval_in_ms(fWall, end_wall); +} diff --git a/tools/timer/SysTimer_posix.h b/tools/timer/SysTimer_posix.h new file mode 100644 index 0000000000..1eca909e26 --- /dev/null +++ b/tools/timer/SysTimer_posix.h @@ -0,0 +1,23 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef SysTimer_DEFINED +#define SysTimer_DEFINED + +#include + +class SysTimer { +public: + void startWall(); + void startCpu(); + double endCpu(); + double endWall(); +private: + timespec fCpu; + timespec fWall; +}; + +#endif diff --git a/tools/timer/SysTimer_windows.cpp b/tools/timer/SysTimer_windows.cpp new file mode 100644 index 0000000000..2f9d0a5d58 --- /dev/null +++ b/tools/timer/SysTimer_windows.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "SysTimer_windows.h" + +static ULONGLONG win_cpu_time() { + FILETIME createTime; + FILETIME exitTime; + FILETIME usrTime; + FILETIME sysTime; + if (0 == GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &sysTime, &usrTime)) { + return 0; + } + ULARGE_INTEGER start_cpu_sys; + ULARGE_INTEGER start_cpu_usr; + start_cpu_sys.LowPart = sysTime.dwLowDateTime; + start_cpu_sys.HighPart = sysTime.dwHighDateTime; + start_cpu_usr.LowPart = usrTime.dwLowDateTime; + start_cpu_usr.HighPart = usrTime.dwHighDateTime; + return start_cpu_sys.QuadPart + start_cpu_usr.QuadPart; +} + +void SysTimer::startWall() { + if (0 == ::QueryPerformanceCounter(&fStartWall)) { + fStartWall.QuadPart = 0; + } +} +void SysTimer::startCpu() { + fStartCpu = win_cpu_time(); +} + +double SysTimer::endCpu() { + ULONGLONG end_cpu = win_cpu_time(); + return static_cast(end_cpu - fStartCpu) / 10000.0L; +} +double SysTimer::endWall() { + LARGE_INTEGER end_wall; + if (0 == ::QueryPerformanceCounter(&end_wall)) { + end_wall.QuadPart = 0; + } + + LARGE_INTEGER ticks_elapsed; + ticks_elapsed.QuadPart = end_wall.QuadPart - fStartWall.QuadPart; + + LARGE_INTEGER frequency; + if (0 == ::QueryPerformanceFrequency(&frequency)) { + return 0.0L; + } else { + return static_cast(ticks_elapsed.QuadPart) + / static_cast(frequency.QuadPart) + * 1000.0L; + } +} diff --git a/tools/timer/SysTimer_windows.h b/tools/timer/SysTimer_windows.h new file mode 100644 index 0000000000..62a9445134 --- /dev/null +++ b/tools/timer/SysTimer_windows.h @@ -0,0 +1,25 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef SysTimer_DEFINED +#define SysTimer_DEFINED + +//Time +#define WIN32_LEAN_AND_MEAN 1 +#include + +class SysTimer { +public: + void startWall(); + void startCpu(); + double endCpu(); + double endWall(); +private: + ULONGLONG fStartCpu; + LARGE_INTEGER fStartWall; +}; + +#endif diff --git a/tools/timer/Timer.cpp b/tools/timer/Timer.cpp new file mode 100644 index 0000000000..4f3fc85cff --- /dev/null +++ b/tools/timer/Timer.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "Timer.h" + +Timer::Timer(SkGLContextHelper* gl) + : fCpu(-1.0) + , fWall(-1.0) + , fTruncatedCpu(-1.0) + , fTruncatedWall(-1.0) + , fGpu(-1.0) +#if SK_SUPPORT_GPU + , fGpuTimer(gl) +#endif + {} + +void Timer::start() { + fSysTimer.startWall(); + fTruncatedSysTimer.startWall(); +#if SK_SUPPORT_GPU + fGpuTimer.start(); +#endif + fSysTimer.startCpu(); + fTruncatedSysTimer.startCpu(); +} + +void Timer::end() { + fCpu = fSysTimer.endCpu(); +#if SK_SUPPORT_GPU + //It is important to stop the cpu clocks first, + //as the following will cpu wait for the gpu to finish. + fGpu = fGpuTimer.end(); +#endif + fWall = fSysTimer.endWall(); +} + +void Timer::truncatedEnd() { + fTruncatedCpu = fTruncatedSysTimer.endCpu(); + fTruncatedWall = fTruncatedSysTimer.endWall(); +} + +WallTimer::WallTimer() : fWall(-1.0) {} + +void WallTimer::start() { + fSysTimer.startWall(); +} + +void WallTimer::end() { + fWall = fSysTimer.endWall(); +} diff --git a/tools/timer/Timer.h b/tools/timer/Timer.h new file mode 100644 index 0000000000..7a91ac6e53 --- /dev/null +++ b/tools/timer/Timer.h @@ -0,0 +1,73 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef Timer_DEFINED +#define Timer_DEFINED + +#include "SkTypes.h" + +#if defined(SK_BUILD_FOR_WIN32) + #include "SysTimer_windows.h" +#elif defined(SK_BUILD_FOR_MAC) + #include "SysTimer_mach.h" +#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) + #include "SysTimer_posix.h" +#endif + +#if SK_SUPPORT_GPU + #include "GpuTimer.h" +#endif + +class SkGLContextHelper; + +/** + * SysTimers and GpuTimers are implemented orthogonally. + * This class combines 2 SysTimers and a GpuTimer into one single, + * platform specific Timer with a simple interface. The truncated + * timer doesn't include the time required for the GPU to finish + * its rendering. It should always be <= the un-truncated system + * times and (for GPU configurations) can be used to roughly (very + * roughly) gauge the GPU load/backlog. + */ +class Timer { +public: + explicit Timer(SkGLContextHelper* gl = NULL); + + void start(); + void truncatedEnd(); + void end(); + + // All times in milliseconds. + double fCpu; + double fWall; + double fTruncatedCpu; + double fTruncatedWall; + double fGpu; + +private: + SysTimer fSysTimer; + SysTimer fTruncatedSysTimer; +#if SK_SUPPORT_GPU + GpuTimer fGpuTimer; +#endif +}; + +// Same as Timer above, supporting only fWall but with much lower overhead. +// (Typically, ~30ns instead of Timer's ~1us.) +class WallTimer { +public: + WallTimer(); + + void start(); + void end(); + + double fWall; // Milliseconds. + +private: + SysTimer fSysTimer; +}; + +#endif diff --git a/tools/timer/TimerData.cpp b/tools/timer/TimerData.cpp new file mode 100644 index 0000000000..21529bc2e0 --- /dev/null +++ b/tools/timer/TimerData.cpp @@ -0,0 +1,220 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "TimerData.h" + +#include "Timer.h" +#include + +TimerData::TimerData(int maxNumTimings) + : fMaxNumTimings(maxNumTimings) + , fCurrTiming(0) + , fWallTimes(maxNumTimings) + , fTruncatedWallTimes(maxNumTimings) + , fCpuTimes(maxNumTimings) + , fTruncatedCpuTimes(maxNumTimings) + , fGpuTimes(maxNumTimings) {} + +bool TimerData::appendTimes(Timer* timer) { + SkASSERT(timer != NULL); + if (fCurrTiming >= fMaxNumTimings) { + return false; + } + + fWallTimes[fCurrTiming] = timer->fWall; + fTruncatedWallTimes[fCurrTiming] = timer->fTruncatedWall; + fCpuTimes[fCurrTiming] = timer->fCpu; + fTruncatedCpuTimes[fCurrTiming] = timer->fTruncatedCpu; + fGpuTimes[fCurrTiming] = timer->fGpu; + + ++fCurrTiming; + + return true; +} + +SkString TimerData::getResult(const char* doubleFormat, + Result result, + const char *configName, + uint32_t timerFlags, + int itersPerTiming) { + SkASSERT(itersPerTiming >= 1); + + if (!fCurrTiming) { + return SkString(""); + } + + int numTimings = fCurrTiming; + + SkString wallStr(" msecs = "); + SkString truncWallStr(" Wmsecs = "); + SkString cpuStr(" cmsecs = "); + SkString truncCpuStr(" Cmsecs = "); + SkString gpuStr(" gmsecs = "); + + double wallMin = std::numeric_limits::max(); + double truncWallMin = std::numeric_limits::max(); + double cpuMin = std::numeric_limits::max(); + double truncCpuMin = std::numeric_limits::max(); + double gpuMin = std::numeric_limits::max(); + + double wallSum = 0; + double truncWallSum = 0; + double cpuSum = 0; + double truncCpuSum = 0; + double gpuSum = 0; + + for (int i = 0; i < numTimings; ++i) { + if (kPerIter_Result == result) { + wallStr.appendf(doubleFormat, fWallTimes[i] / itersPerTiming); + truncWallStr.appendf(doubleFormat, fTruncatedWallTimes[i] / itersPerTiming); + cpuStr.appendf(doubleFormat, fCpuTimes[i] / itersPerTiming); + truncCpuStr.appendf(doubleFormat, fTruncatedCpuTimes[i] / itersPerTiming); + gpuStr.appendf(doubleFormat, fGpuTimes[i] / itersPerTiming); + + if (i != numTimings - 1) { + static const char kSep[] = ", "; + wallStr.append(kSep); + truncWallStr.append(kSep); + cpuStr.append(kSep); + truncCpuStr.append(kSep); + gpuStr.append(kSep); + } + } else if (kMin_Result == result) { + wallMin = SkTMin(wallMin, fWallTimes[i]); + truncWallMin = SkTMin(truncWallMin, fTruncatedWallTimes[i]); + cpuMin = SkTMin(cpuMin, fCpuTimes[i]); + truncCpuMin = SkTMin(truncCpuMin, fTruncatedCpuTimes[i]); + gpuMin = SkTMin(gpuMin, fGpuTimes[i]); + } else { + SkASSERT(kAvg_Result == result); + wallSum += fWallTimes[i]; + truncWallSum += fTruncatedWallTimes[i]; + cpuSum += fCpuTimes[i]; + truncCpuSum += fTruncatedCpuTimes[i]; + } + + // We always track the GPU sum because whether it is non-zero indicates if valid gpu times + // were recorded at all. + gpuSum += fGpuTimes[i]; + } + + if (kMin_Result == result) { + wallStr.appendf(doubleFormat, wallMin / itersPerTiming); + truncWallStr.appendf(doubleFormat, truncWallMin / itersPerTiming); + cpuStr.appendf(doubleFormat, cpuMin / itersPerTiming); + truncCpuStr.appendf(doubleFormat, truncCpuMin / itersPerTiming); + gpuStr.appendf(doubleFormat, gpuMin / itersPerTiming); + } else if (kAvg_Result == result) { + int divisor = numTimings * itersPerTiming; + wallStr.appendf(doubleFormat, wallSum / divisor); + truncWallStr.appendf(doubleFormat, truncWallSum / divisor); + cpuStr.appendf(doubleFormat, cpuSum / divisor); + truncCpuStr.appendf(doubleFormat, truncCpuSum / divisor); + gpuStr.appendf(doubleFormat, gpuSum / divisor); + } + + SkString str; + str.printf(" %4s:", configName); + if (timerFlags & kWall_Flag) { + str += wallStr; + } + if (timerFlags & kTruncatedWall_Flag) { + str += truncWallStr; + } + if (timerFlags & kCpu_Flag) { + str += cpuStr; + } + if (timerFlags & kTruncatedCpu_Flag) { + str += truncCpuStr; + } + if ((timerFlags & kGpu_Flag) && gpuSum > 0) { + str += gpuStr; + } + return str; +} + +Json::Value TimerData::getJSON(uint32_t timerFlags, + Result result, + int itersPerTiming) { + SkASSERT(itersPerTiming >= 1); + Json::Value dataNode; + Json::Value wallNode, truncWall, cpuNode, truncCpu, gpuNode; + if (!fCurrTiming) { + return dataNode; + } + + int numTimings = fCurrTiming; + + double wallMin = std::numeric_limits::max(); + double truncWallMin = std::numeric_limits::max(); + double cpuMin = std::numeric_limits::max(); + double truncCpuMin = std::numeric_limits::max(); + double gpuMin = std::numeric_limits::max(); + + double wallSum = 0; + double truncWallSum = 0; + double cpuSum = 0; + double truncCpuSum = 0; + double gpuSum = 0; + + for (int i = 0; i < numTimings; ++i) { + if (kPerIter_Result == result) { + wallNode.append(fWallTimes[i] / itersPerTiming); + truncWall.append(fTruncatedWallTimes[i] / itersPerTiming); + cpuNode.append(fCpuTimes[i] / itersPerTiming); + truncCpu.append(fTruncatedCpuTimes[i] / itersPerTiming); + gpuNode.append(fGpuTimes[i] / itersPerTiming); + } else if (kMin_Result == result) { + wallMin = SkTMin(wallMin, fWallTimes[i]); + truncWallMin = SkTMin(truncWallMin, fTruncatedWallTimes[i]); + cpuMin = SkTMin(cpuMin, fCpuTimes[i]); + truncCpuMin = SkTMin(truncCpuMin, fTruncatedCpuTimes[i]); + gpuMin = SkTMin(gpuMin, fGpuTimes[i]); + } else { + SkASSERT(kAvg_Result == result); + wallSum += fWallTimes[i]; + truncWallSum += fTruncatedWallTimes[i]; + cpuSum += fCpuTimes[i]; + truncCpuSum += fTruncatedCpuTimes[i]; + } + + // We always track the GPU sum because whether it is non-zero indicates if valid gpu times + // were recorded at all. + gpuSum += fGpuTimes[i]; + } + + if (kMin_Result == result) { + wallNode.append(wallMin / itersPerTiming); + truncWall.append(truncWallMin / itersPerTiming); + cpuNode.append(cpuMin / itersPerTiming); + truncCpu.append(truncCpuMin / itersPerTiming); + gpuNode.append(gpuMin / itersPerTiming); + } else if (kAvg_Result == result) { + int divisor = numTimings * itersPerTiming; + wallNode.append(wallSum / divisor); + truncWall.append(truncWallSum / divisor); + cpuNode.append(cpuSum / divisor); + truncCpu.append(truncCpuSum / divisor); + gpuNode.append(gpuSum / divisor); + } + + if (timerFlags & kWall_Flag) { + dataNode["wall"] = wallNode; + } + if (timerFlags & kTruncatedWall_Flag) { + dataNode["truncWall"] = truncWall; + } + if (timerFlags & kCpu_Flag) { + dataNode["cpu"] = cpuNode; + } + if (timerFlags & kTruncatedCpu_Flag) { + dataNode["trucCpu"] = truncCpu; + } + if ((timerFlags & kGpu_Flag) && gpuSum > 0) { + dataNode["gpu"] = gpuNode; + } + return dataNode; +} diff --git a/tools/timer/TimerData.h b/tools/timer/TimerData.h new file mode 100644 index 0000000000..35e94dca1d --- /dev/null +++ b/tools/timer/TimerData.h @@ -0,0 +1,85 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef TimerData_DEFINED +#define TimerData_DEFINED + +#include "SkString.h" +#include "SkTemplates.h" + +#ifdef SK_BUILD_FOR_WIN + #pragma warning(push) + #pragma warning(disable : 4530) +#endif + +#include "SkJSONCPP.h" + +#ifdef SK_BUILD_FOR_WIN + #pragma warning(pop) +#endif + +class Timer; + +class TimerData { +public: + /** + * Constructs a TimerData to hold at most maxNumTimings sets of elapsed timer values. + **/ + explicit TimerData(int maxNumTimings); + + /** + * Collect times from the Timer for an iteration. It will fail if called more often than + * indicated in the constructor. + * + * @param Timer Must not be null. + */ + bool appendTimes(Timer*); + + enum Result { + kMin_Result, + kAvg_Result, + kPerIter_Result + }; + + enum TimerFlags { + kWall_Flag = 0x1, + kTruncatedWall_Flag = 0x2, + kCpu_Flag = 0x4, + kTruncatedCpu_Flag = 0x8, + kGpu_Flag = 0x10 + }; + + /** + * Gets the timer data results as a string. + * @param doubleFormat printf-style format for doubles (e.g. "%02d") + * @param result the type of result desired + * @param the name of the config being timed (prepended to results string) + * @param timerFlags bitfield of TimerFlags values indicating which timers should be reported. + * @param itersPerTiming the number of test/bench iterations that correspond to each + * appendTimes() call, 1 when appendTimes is called for each iteration. + */ + SkString getResult(const char* doubleFormat, + Result result, + const char* configName, + uint32_t timerFlags, + int itersPerTiming = 1); + Json::Value getJSON(uint32_t timerFlags, + Result result, + int itersPerTiming = 1); + +private: + int fMaxNumTimings; + int fCurrTiming; + + SkAutoTArray fWallTimes; + SkAutoTArray fTruncatedWallTimes; + SkAutoTArray fCpuTimes; + SkAutoTArray fTruncatedCpuTimes; + SkAutoTArray fGpuTimes; +}; + +#endif // TimerData_DEFINED -- cgit v1.2.3