Bug 1614635: Keep waiting on the remote canvas writer side while the reader hasn't closed. r=jrmuizel
authorBob Owen <bobowencode@gmail.com>
Mon, 24 Feb 2020 10:53:48 +0000
changeset 515245 988672936c1bc88647ca7fa88b35e26d71de7f8f
parent 515244 d2a8ac40ce6b0af1615fe81a36cb605d9c1f0e78
child 515246 c93553460bfd52dca5a06f0546f7daa3382ef98b
push id37154
push usercsabou@mozilla.com
push dateMon, 24 Feb 2020 16:27:17 +0000
treeherdermozilla-central@8c5f9b08938e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1614635
milestone75.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 1614635: Keep waiting on the remote canvas writer side while the reader hasn't closed. r=jrmuizel It seems clear that we can get long delays waiting for Direct2D to process things on occasion. So given that we now detect when the reader has closed, instead of guessing at a suitably long timeout, waiting indefintely while it hasn't closed seems like a better option. This gives a similar behaviour to when this is just running in the content process, because that just has to wait on any long running Direct2D calls. Differential Revision: https://phabricator.services.mozilla.com/D62464
gfx/layers/CanvasDrawEventRecorder.cpp
gfx/layers/CanvasDrawEventRecorder.h
--- a/gfx/layers/CanvasDrawEventRecorder.cpp
+++ b/gfx/layers/CanvasDrawEventRecorder.cpp
@@ -336,17 +336,17 @@ int32_t CanvasEventRingBuffer::ReadNextE
 }
 
 uint32_t CanvasEventRingBuffer::CreateCheckpoint() {
   WriteElement(*this, kCheckpointEventType);
   return mOurCount;
 }
 
 bool CanvasEventRingBuffer::WaitForCheckpoint(uint32_t aCheckpoint) {
-  return WaitForReadCount(aCheckpoint, kTimeout, kTimeoutRetryCount);
+  return WaitForReadCount(aCheckpoint, kTimeout);
 }
 
 void CanvasEventRingBuffer::CheckAndSignalWriter() {
   do {
     switch (mWrite->state) {
       case State::Processing:
         return;
       case State::AboutToWait:
@@ -366,18 +366,17 @@ void CanvasEventRingBuffer::CheckAndSign
       default:
         MOZ_ASSERT_UNREACHABLE("Invalid waiting state.");
         return;
     }
   } while (true);
 }
 
 bool CanvasEventRingBuffer::WaitForReadCount(uint32_t aReadCount,
-                                             TimeDuration aTimeout,
-                                             int32_t aRetryCount) {
+                                             TimeDuration aTimeout) {
   uint32_t requiredDifference = mOurCount - aReadCount;
   uint32_t spinCount = kMaxSpinCount;
   do {
     if (mOurCount - mRead->count <= requiredDifference) {
       return true;
     }
   } while (--spinCount != 0);
 
@@ -387,36 +386,30 @@ bool CanvasEventRingBuffer::WaitForReadC
   if (mOurCount - mRead->count <= requiredDifference) {
     mWrite->state = State::Processing;
     return true;
   }
 
   mWrite->requiredDifference = requiredDifference;
   mWrite->state = State::Waiting;
 
-  do {
+  // Wait unless we detect the reading side has closed.
+  while (!mWriterServices->ReaderClosed()) {
     if (mWriterSemaphore->Wait(Some(aTimeout))) {
       MOZ_ASSERT(mOurCount - mRead->count <= requiredDifference);
       return true;
     }
-
-    if (mWriterServices->ReaderClosed()) {
-      // Something has gone wrong on the reading side, just return false so
-      // that we can hopefully recover.
-      return false;
-    }
-  } while (aRetryCount-- > 0);
+  }
 
   return false;
 }
 
 uint32_t CanvasEventRingBuffer::WaitForBytesToWrite() {
   uint32_t streamFullReadCount = mOurCount - kStreamSize;
-  if (!WaitForReadCount(streamFullReadCount + 1, kTimeout,
-                        kTimeoutRetryCount)) {
+  if (!WaitForReadCount(streamFullReadCount + 1, kTimeout)) {
     mGood = false;
     return 0;
   }
 
   return mRead->count - streamFullReadCount;
 }
 
 uint32_t CanvasEventRingBuffer::WaitForBytesToRead() {
--- a/gfx/layers/CanvasDrawEventRecorder.h
+++ b/gfx/layers/CanvasDrawEventRecorder.h
@@ -194,18 +194,17 @@ class CanvasEventRingBuffer final : publ
     Atomic<State, ReleaseAcquire> state;
   };
 
   CanvasEventRingBuffer(const CanvasEventRingBuffer&) = delete;
   void operator=(const CanvasEventRingBuffer&) = delete;
 
   void IncrementWriteCountBy(uint32_t aCount);
 
-  bool WaitForReadCount(uint32_t aReadCount, TimeDuration aTimeout,
-                        int32_t aRetryCount);
+  bool WaitForReadCount(uint32_t aReadCount, TimeDuration aTimeout);
 
   bool WaitForAndRecalculateAvailableData();
 
   void UpdateReadTotalsBy(uint32_t aCount);
   void IncrementReadCountBy(uint32_t aCount);
 
   void CheckAndSignalReader();