Bug 1579127 - only count the frame dropping due to system overload. r=mattwoodrow
authoralwu <alwu@mozilla.com>
Tue, 08 Oct 2019 08:06:13 +0000
changeset 496729 fabb105bcda3ac8f8aefa13fea3624fdadd2f1c4
parent 496728 42de2e88ff5508db6c7e929862dca28cf09dbd63
child 496730 379a22d155982c7f109dc60d7a98bfd67fdff664
push id97396
push useralwu@mozilla.com
push dateTue, 08 Oct 2019 08:06:54 +0000
treeherderautoland@379a22d15598 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1579127
milestone71.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1579127 - only count the frame dropping due to system overload. r=mattwoodrow When user adjusts the video playback rate, which might cause we sending images in a speed that is faster than the speend we composite images. In this situation, the frame dropping actually won't cause any visual defect and we also don't want to report this frame dropping to user, because it's not caused by system overloading, it's just our compositor doesn't support compositing images in such a high rate. Therefore, we should check if the dropped images are caused by system overload or high update rate, and only report the former to user. Differential Revision: https://phabricator.services.mozilla.com/D46236
gfx/layers/composite/ImageComposite.cpp
gfx/layers/composite/ImageComposite.h
--- a/gfx/layers/composite/ImageComposite.cpp
+++ b/gfx/layers/composite/ImageComposite.cpp
@@ -1,16 +1,18 @@
 /* -*- 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/. */
 
 #include "ImageComposite.h"
 
+#include "gfxPlatform.h"
+
 namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
 
 /* static */ const float ImageComposite::BIAS_TIME_MS = 1.0f;
 
@@ -106,18 +108,24 @@ int ImageComposite::ChooseImageIndex() {
   while (result + 1 < mImages.Length() &&
          GetBiasedTime(mImages[result + 1].mTimeStamp) <= now) {
     ++result;
   }
   if (result - mLastChosenImageIndex > 1) {
     // We're not returning the same image as the last call to ChooseImageIndex
     // or the immediately next one. We can assume that the frames not returned
     // have been dropped as they were too late to be displayed
-    mDroppedFrames += result - mLastChosenImageIndex - 1;
-    PROFILER_ADD_MARKER("Video frames dropped", GRAPHICS);
+    for (size_t idx = mLastChosenImageIndex; idx <= result; idx++) {
+      if (IsImagesUpdateRateFasterThanCompositedRate(mImages[result],
+                                                     mImages[idx])) {
+        continue;
+      }
+      mDroppedFrames++;
+      PROFILER_ADD_MARKER("Video frames dropped", GRAPHICS);
+    }
   }
   mLastChosenImageIndex = result;
   return result;
 }
 
 const ImageComposite::TimedImage* ImageComposite::ChooseImage() {
   int index = ChooseImageIndex();
   return index >= 0 ? &mImages[index] : nullptr;
@@ -169,16 +177,20 @@ uint32_t ImageComposite::ScanForLastFram
     }
     if (oldFrameID < newFrameID) {
       // This is a new image, all images prior the new one and not yet
       // rendered can be considered as dropped. Those images have a FrameID
       // inferior to the new image.
       for (++i; i < mImages.Length() && mImages[i].mFrameID < newFrameID &&
                 mImages[i].mProducerID == aNewImages[j].mProducerID;
            i++) {
+        if (IsImagesUpdateRateFasterThanCompositedRate(aNewImages[j],
+                                                       mImages[i])) {
+          continue;
+        }
         dropped++;
       }
       break;
     }
     i++;
     j++;
   }
   if (dropped > 0) {
@@ -201,10 +213,22 @@ void ImageComposite::SetImages(nsTArray<
 const ImageComposite::TimedImage* ImageComposite::GetImage(
     size_t aIndex) const {
   if (aIndex >= mImages.Length()) {
     return nullptr;
   }
   return &mImages[aIndex];
 }
 
+bool ImageComposite::IsImagesUpdateRateFasterThanCompositedRate(
+    const TimedImage& aNewImage, const TimedImage& aOldImage) const {
+  MOZ_ASSERT(aNewImage.mFrameID >= aOldImage.mFrameID);
+  const uint32_t compositedRate = gfxPlatform::TargetFrameRate();
+  if (compositedRate == 0) {
+    return true;
+  }
+  const double compositedInterval = 1.0 / compositedRate;
+  return aNewImage.mTimeStamp - aOldImage.mTimeStamp <
+         TimeDuration::FromSeconds(compositedInterval);
+}
+
 }  // namespace layers
 }  // namespace mozilla
--- a/gfx/layers/composite/ImageComposite.h
+++ b/gfx/layers/composite/ImageComposite.h
@@ -88,16 +88,23 @@ class ImageComposite {
   nsTArray<TimedImage> mImages;
   TimeStamp GetBiasedTime(const TimeStamp& aInput) const;
   // Scan new images and look for common ones in the existing mImages array.
   // Will determine if an image has been dropped through gaps between images and
   // adjust mDroppedFrames accordingly.
   // Return the index of what the last returned image would have been.
   uint32_t ScanForLastFrameIndex(const nsTArray<TimedImage>& aNewImages);
 
+  // Return true if we send image in a speed which is faster than the one we can
+  // composite image. It's used to decide whether we should report the frame
+  // dropping, because we only want to know the frame dropping, which is caused
+  // by machine overload.
+  bool IsImagesUpdateRateFasterThanCompositedRate(
+      const TimedImage& aNewImage, const TimedImage& aOldImage) const;
+
   /**
    * Bias to apply to the next frame.
    */
   Bias mBias;
   uint32_t mDroppedFrames;
   uint32_t mLastChosenImageIndex;
 };