1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "Diagnostics.h"
8 #include "mozilla/layers/LayersMessages.h"
9 #include "nsPrintfCString.h"
10 
11 namespace mozilla {
12 namespace layers {
13 
Average() const14 float TimedMetric::Average() const {
15   // We take at most 2 seconds of history.
16   TimeStamp latest = TimeStamp::Now();
17   float total = 0.0f;
18   size_t count = 0;
19   for (auto iter = mHistory.rbegin(); iter != mHistory.rend(); iter++) {
20     if ((latest - iter->second).ToSeconds() > 2.0f) {
21       break;
22     }
23     total += iter->first;
24     count++;
25   }
26 
27   if (!count) {
28     return 0.0f;
29   }
30   return total / float(count);
31 }
32 
Diagnostics()33 Diagnostics::Diagnostics()
34     : mCompositeFps("Compositor"), mTransactionFps("LayerTransactions") {}
35 
RecordPaintTimes(const PaintTiming & aPaintTimes)36 void Diagnostics::RecordPaintTimes(const PaintTiming& aPaintTimes) {
37   mDlbMs.Add(aPaintTimes.dlMs());
38   mDlb2Ms.Add(aPaintTimes.dl2Ms());
39   mFlbMs.Add(aPaintTimes.flbMs());
40   mRasterMs.Add(aPaintTimes.rasterMs());
41   mSerializeMs.Add(aPaintTimes.serializeMs());
42   mSendMs.Add(aPaintTimes.sendMs());
43 }
44 
GetFrameOverlayString(const GPUStats & aStats)45 std::string Diagnostics::GetFrameOverlayString(const GPUStats& aStats) {
46   TimeStamp now = TimeStamp::Now();
47   unsigned fps = unsigned(mCompositeFps.AddFrameAndGetFps(now));
48   unsigned txnFps = unsigned(mTransactionFps.GetFPS(now));
49 
50   float pixelFillRatio =
51       aStats.mInvalidPixels
52           ? float(aStats.mPixelsFilled) / float(aStats.mInvalidPixels)
53           : 0.0f;
54   float screenFillRatio = aStats.mScreenPixels ? float(aStats.mPixelsFilled) /
55                                                      float(aStats.mScreenPixels)
56                                                : 0.0f;
57 
58   if (aStats.mDrawTime) {
59     mGPUDrawMs.Add(aStats.mDrawTime.value());
60   }
61 
62   std::string gpuTimeString;
63   if (mGPUDrawMs.Empty()) {
64     gpuTimeString = "N/A";
65   } else {
66     gpuTimeString = nsPrintfCString("%0.1fms", mGPUDrawMs.Average()).get();
67   }
68 
69   // DL  = nsDisplayListBuilder, p = partial, f = full
70   // FLB = FrameLayerBuilder
71   // R   = ClientLayerManager::EndTransaction
72   // CP  = ShadowLayerForwarder::EndTransaction (txn build)
73   // TX  = LayerTransactionChild::SendUpdate (IPDL serialize+send)
74   // UP  = LayerTransactionParent::RecvUpdate (IPDL deserialize, update, APZ
75   //                                           update)
76   // CC_BUILD = Container prepare/composite frame building
77   // CC_EXEC  = Container render/composite drawing
78   nsPrintfCString line1("FPS: %d (TXN: %d)", fps, txnFps);
79   nsPrintfCString line2(
80       "[CC] Build: %0.1fms Exec: %0.1fms GPU: %s Fill Ratio: %0.1f/%0.1f",
81       mPrepareMs.Average(), mCompositeMs.Average(), gpuTimeString.c_str(),
82       pixelFillRatio, screenFillRatio);
83   nsPrintfCString line3(
84       "[Content] DL p: %0.1f DL f: %0.1fms FLB: %0.1fms Raster: %0.1fms",
85       mDlbMs.Average(), mDlb2Ms.Average(), mFlbMs.Average(),
86       mRasterMs.Average());
87   nsPrintfCString line4("[IPDL] Build: %0.1fms Send: %0.1fms Update: %0.1fms",
88                         mSerializeMs.Average(), mSendMs.Average(),
89                         mUpdateMs.Average());
90 
91   return std::string(line1.get()) + "\n" + std::string(line2.get()) + "\n" +
92          std::string(line3.get()) + "\n" + std::string(line4.get());
93 }
94 
95 }  // namespace layers
96 }  // namespace mozilla
97