Bug 1579127 - only count the frame dropping due to system overload. r=mattwoodrow, a=RyanVM
authoralwu <alwu@mozilla.com>
Tue, 08 Oct 2019 08:06:13 +0000
changeset 524141 fc92c73816af233a86d93afb90890d7845580fc4
parent 524140 ab1de3d63d0a0bc4f65d7c91acdfc0051f3cbfc6
child 524142 f637cbfabf006c7f01d71a12ea7ca1b89684c84b
push id617
push userryanvm@gmail.com
push dateThu, 21 Nov 2019 16:27:44 +0000
treeherdermozilla-esr68@bf5e67b06638 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow, RyanVM
bugs1579127
milestone68.3.0
Bug 1579127 - only count the frame dropping due to system overload. r=mattwoodrow, a=RyanVM 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;
 };