tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PerformanceRecorder.cpp (7561B)


      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 "PerformanceRecorder.h"
      8 
      9 #include "base/process_util.h"
     10 #include "mozilla/Logging.h"
     11 #include "mozilla/gfx/Types.h"
     12 #include "nsPrintfCString.h"
     13 
     14 namespace mozilla {
     15 
     16 TrackingId::TrackingId() : mSource(Source::Unimplemented), mUniqueInProcId(0) {}
     17 
     18 TrackingId::TrackingId(
     19    Source aSource, uint32_t aUniqueInProcId,
     20    TrackAcrossProcesses aTrack /* = TrackAcrossProcesses::NO */)
     21    : mSource(aSource),
     22      mUniqueInProcId(aUniqueInProcId),
     23      mProcId(aTrack == TrackAcrossProcesses::Yes
     24                  ? Some(base::GetCurrentProcId())
     25                  : Nothing()) {}
     26 
     27 nsCString TrackingId::ToString() const {
     28  if (mProcId) {
     29    return nsPrintfCString("%s-%u-%u", EnumValueToString(mSource), *mProcId,
     30                           mUniqueInProcId);
     31  }
     32  return nsPrintfCString("%s-%u", EnumValueToString(mSource), mUniqueInProcId);
     33 }
     34 
     35 static void AppendMediaInfoFlagToName(nsCString& aName, MediaInfoFlag aFlag) {
     36  if (aFlag & MediaInfoFlag::KeyFrame) {
     37    aName.Append("kf,");
     38  }
     39  // Decoding
     40  if (aFlag & MediaInfoFlag::SoftwareDecoding) {
     41    aName.Append("sw,");
     42  } else if (aFlag & MediaInfoFlag::HardwareDecoding) {
     43    aName.Append("hw,");
     44  }
     45  // Codec type
     46  if (aFlag & MediaInfoFlag::VIDEO_AV1) {
     47    aName.Append("av1,");
     48  } else if (aFlag & MediaInfoFlag::VIDEO_H264) {
     49    aName.Append("h264,");
     50  } else if (aFlag & MediaInfoFlag::VIDEO_VP8) {
     51    aName.Append("vp8,");
     52  } else if (aFlag & MediaInfoFlag::VIDEO_VP9) {
     53    aName.Append("vp9,");
     54  } else if (aFlag & MediaInfoFlag::VIDEO_HEVC) {
     55    aName.Append("hevc,");
     56  }
     57 }
     58 
     59 static void AppendImageFormatToName(nsCString& aName,
     60                                    DecodeStage::ImageFormat aFormat) {
     61  aName.AppendPrintf("%s,", DecodeStage::EnumValueToString(aFormat));
     62 }
     63 
     64 static void AppendYUVColorSpaceToName(nsCString& aName,
     65                                      gfx::YUVColorSpace aSpace) {
     66  aName.Append([&] {
     67    switch (aSpace) {
     68      case gfx::YUVColorSpace::BT601:
     69        return "space=BT.601,";
     70      case gfx::YUVColorSpace::BT709:
     71        return "space=BT.709,";
     72      case gfx::YUVColorSpace::BT2020:
     73        return "space=BT.2020,";
     74      case gfx::YUVColorSpace::Identity:
     75        return "space=Identity,";
     76    }
     77    MOZ_ASSERT_UNREACHABLE("Unhandled gfx::YUVColorSpace");
     78    return "";
     79  }());
     80 }
     81 
     82 static void AppendColorRangeToName(nsCString& aName, gfx::ColorRange aRange) {
     83  aName.Append([&] {
     84    switch (aRange) {
     85      case gfx::ColorRange::LIMITED:
     86        return "range=Limited,";
     87      case gfx::ColorRange::FULL:
     88        return "range=Full,";
     89    }
     90    MOZ_ASSERT_UNREACHABLE("Unhandled gfx::ColorRange");
     91    return "";
     92  }());
     93 }
     94 
     95 static void AppendColorDepthToName(nsCString& aName, gfx::ColorDepth aDepth) {
     96  aName.Append([&] {
     97    switch (aDepth) {
     98      case gfx::ColorDepth::COLOR_8:
     99        return "depth=8,";
    100      case gfx::ColorDepth::COLOR_10:
    101        return "depth=10,";
    102      case gfx::ColorDepth::COLOR_12:
    103        return "depth=12,";
    104      case gfx::ColorDepth::COLOR_16:
    105        return "depth=16,";
    106    }
    107    MOZ_ASSERT_UNREACHABLE("Unhandled gfx::ColorDepth");
    108    return "";
    109  }());
    110 }
    111 
    112 /* static */
    113 const char* FindMediaResolution(int32_t aHeight) {
    114  static const struct {
    115    const int32_t mH;
    116    const nsCString mRes;
    117  } sResolutions[] = {{0, "A:0"_ns},  // other followings are for video
    118                      {240, "V:0<h<=240"_ns},
    119                      {480, "V:240<h<=480"_ns},
    120                      {576, "V:480<h<=576"_ns},
    121                      {720, "V:576<h<=720"_ns},
    122                      {1080, "V:720<h<=1080"_ns},
    123                      {1440, "V:1080<h<=1440"_ns},
    124                      {2160, "V:1440<h<=2160"_ns},
    125                      {INT_MAX, "V:h>2160"_ns}};
    126  const char* resolution = sResolutions[0].mRes.get();
    127  for (auto&& res : sResolutions) {
    128    if (aHeight <= res.mH) {
    129      resolution = res.mRes.get();
    130      break;
    131    }
    132  }
    133  return resolution;
    134 }
    135 
    136 /* static */
    137 bool PerformanceRecorderBase::IsMeasurementEnabled() {
    138  return profiler_thread_is_being_profiled_for_markers() ||
    139         PerformanceRecorderBase::sEnableMeasurementForTesting;
    140 }
    141 
    142 /* static */
    143 TimeStamp PerformanceRecorderBase::GetCurrentTimeForMeasurement() {
    144  // The system call to get the clock is rather expensive on Windows. As we
    145  // only report the measurement report via markers, if the marker isn't enabled
    146  // then we won't do any measurement in order to save CPU time.
    147  return IsMeasurementEnabled() ? TimeStamp::Now() : TimeStamp();
    148 }
    149 
    150 ProfilerString8View PlaybackStage::Name() const {
    151  if (!mName) {
    152    mName.emplace(EnumValueToString(mStage));
    153    mName->Append(":");
    154    mName->Append(FindMediaResolution(mHeight));
    155    mName->Append(":");
    156    AppendMediaInfoFlagToName(*mName, mFlag);
    157  }
    158  return *mName;
    159 }
    160 
    161 void PlaybackStage::AddMarker(MarkerOptions&& aOption) {
    162  if (mStartAndEndTimeUs) {
    163    auto& pair = *mStartAndEndTimeUs;
    164    profiler_add_marker(Name(), Category(),
    165                        std::forward<MarkerOptions&&>(aOption),
    166                        geckoprofiler::markers::MediaSampleMarker{}, pair.first,
    167                        pair.second, 1 /* queue length */);
    168  } else {
    169    profiler_add_marker(Name(), Category(),
    170                        std::forward<MarkerOptions&&>(aOption));
    171  }
    172 }
    173 
    174 void PlaybackStage::AddFlag(MediaInfoFlag aFlag) { mFlag |= aFlag; }
    175 
    176 ProfilerString8View CaptureStage::Name() const {
    177  if (!mName) {
    178    mName = Some(nsPrintfCString(
    179        "CaptureVideoFrame %s %dx%d %s %s", mSource.Data(), mWidth, mHeight,
    180        EnumValueToString(mImageType), mTrackingId.ToString().get()));
    181  }
    182  return *mName;
    183 }
    184 
    185 ProfilerString8View CopyVideoStage::Name() const {
    186  if (!mName) {
    187    mName =
    188        Some(nsPrintfCString("CopyVideoFrame %s %dx%d %s", mSource.Data(),
    189                             mWidth, mHeight, mTrackingId.ToString().get()));
    190  }
    191  return *mName;
    192 }
    193 
    194 ProfilerString8View DecodeStage::Name() const {
    195  if (!mName) {
    196    nsCString extras;
    197    AppendMediaInfoFlagToName(extras, mFlag);
    198    mImageFormat.apply(
    199        [&](ImageFormat aFormat) { AppendImageFormatToName(extras, aFormat); });
    200    mColorDepth.apply([&](gfx::ColorDepth aDepth) {
    201      AppendColorDepthToName(extras, aDepth);
    202    });
    203    mColorRange.apply([&](gfx::ColorRange aRange) {
    204      AppendColorRangeToName(extras, aRange);
    205    });
    206    mYUVColorSpace.apply([&](gfx::YUVColorSpace aColorSpace) {
    207      AppendYUVColorSpaceToName(extras, aColorSpace);
    208    });
    209    mName = Some(nsPrintfCString("DecodeFrame %s %dx%d %s %s", mSource.Data(),
    210                                 mWidth.valueOr(-1), mHeight.valueOr(-1),
    211                                 extras.get(), mTrackingId.ToString().get()));
    212  }
    213  return *mName;
    214 }
    215 
    216 void DecodeStage::AddMarker(MarkerOptions&& aOption) {
    217  if (mStartAndEndTimeUs) {
    218    auto& pair = *mStartAndEndTimeUs;
    219    profiler_add_marker(Name(), Category(),
    220                        std::forward<MarkerOptions&&>(aOption),
    221                        geckoprofiler::markers::MediaSampleMarker{}, pair.first,
    222                        pair.second, 1 /* queue length */);
    223  } else {
    224    profiler_add_marker(Name(), Category(),
    225                        std::forward<MarkerOptions&&>(aOption));
    226  }
    227 }
    228 
    229 }  // namespace mozilla