diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /gfx/layers/composite/FPSCounter.h | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/layers/composite/FPSCounter.h')
-rw-r--r-- | gfx/layers/composite/FPSCounter.h | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/gfx/layers/composite/FPSCounter.h b/gfx/layers/composite/FPSCounter.h new file mode 100644 index 0000000000..c61b13a7b5 --- /dev/null +++ b/gfx/layers/composite/FPSCounter.h @@ -0,0 +1,102 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_layers_opengl_FPSCounter_h_ +#define mozilla_layers_opengl_FPSCounter_h_ + +#include <algorithm> // for min +#include <stddef.h> // for size_t +#include <map> // for std::map +#include "GLDefs.h" // for GLuint +#include "mozilla/RefPtr.h" // for already_AddRefed, RefCounted +#include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration +#include "nsTArray.h" // for AutoTArray, nsTArray_Impl, etc +#include "prio.h" // for NSPR file i/o + +namespace mozilla { +namespace layers { + +class DataTextureSource; +class Compositor; + +// Dump the FPS histogram every 10 seconds or kMaxFrameFPS +const int kFpsDumpInterval = 10; + +// On desktop, we can have 240 hz monitors, so 10 seconds +// times 240 frames = 2400 +const int kMaxFrames = 2400; + +/** + * The FPSCounter tracks how often we composite or have a layer transaction. + * At each composite / layer transaction, we record the timestamp. + * After kFpsDumpInterval number of composites / transactions, we calculate + * the average and standard deviation of frames composited. We dump a histogram, + * which allows for more statistically significant measurements. We also dump + * absolute frame composite times to a file on the device. + * The FPS counters displayed on screen are based on how many frames we + * composited within the last ~1 second. The more accurate measurement is to + * grab the histogram from stderr or grab the FPS timestamp dumps written to + * file. + * + * To enable dumping to file, enable + * layers.acceleration.draw-fps.write-to-file pref. + + double AddFrameAndGetFps(TimeStamp aCurrentFrame) { + AddFrame(aCurrentFrame); + return EstimateFps(aCurrentFrame); + } + * To enable printing histogram data to logcat, + * enable layers.acceleration.draw-fps.print-histogram + * + * Use the HasNext(), GetNextTimeStamp() like an iterator to read the data, + * backwards in time. This abstracts away the mechanics of reading the data. + */ +class FPSCounter final { + public: + explicit FPSCounter(const char* aName); + ~FPSCounter(); + + void AddFrame(TimeStamp aTimestamp); + double AddFrameAndGetFps(TimeStamp aTimestamp); + double GetFPS(TimeStamp aTimestamp); + + private: + void Init(); + bool CapturedFullInterval(TimeStamp aTimestamp); + + // Used while iterating backwards over the data + void ResetReverseIterator(); + bool HasNext(TimeStamp aTimestamp, double aDuration = kFpsDumpInterval); + TimeStamp GetNextTimeStamp(); + int GetLatestReadIndex(); + TimeStamp GetLatestTimeStamp(); + void WriteFrameTimeStamps(PRFileDesc* fd); + bool IteratedFullInterval(TimeStamp aTimestamp, double aDuration); + + void PrintFPS(); + int BuildHistogram(std::map<int, int>& aHistogram); + void PrintHistogram(std::map<int, int>& aHistogram); + double GetMean(std::map<int, int> aHistogram); + double GetStdDev(std::map<int, int> aHistogram); + nsresult WriteFrameTimeStamps(); + + /*** + * mFrameTimestamps is a psuedo circular buffer + * Since we have a constant write time and don't + * read at an offset except our latest write + * we don't need an explicit read pointer. + */ + AutoTArray<TimeStamp, kMaxFrames> mFrameTimestamps; + int mWriteIndex; // points to next open write slot + int mIteratorIndex; // used only when iterating + const char* mFPSName; + TimeStamp mLastInterval; +}; + +} // namespace layers +} // namespace mozilla + +#endif // mozilla_layers_opengl_FPSCounter_h_ |