Bug 1488808 Part 17 - Allow paints to happen at the normal time when recording/replaying, r=nical.
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 17 Oct 2018 10:16:30 -0600
changeset 490284 7f2e0b3603b4edd4b540ba394943b65e5e44fb41
parent 490283 09a979b6e583eab5833722f358c3a26e0b89a3a2
child 490285 0fba5665bc65c55a4d1f27905a2a60396dbe2bb8
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersnical
bugs1488808
milestone64.0a1
Bug 1488808 Part 17 - Allow paints to happen at the normal time when recording/replaying, r=nical.
gfx/layers/ipc/ShadowLayers.cpp
layout/ipc/VsyncChild.cpp
xpcom/threads/nsThread.cpp
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -777,25 +777,26 @@ ShadowLayerForwarder::EndTransaction(con
 
   MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction..."));
   RenderTraceScope rendertrace3("Forward Transaction", "000093");
   if (!mShadowManager->SendUpdate(info)) {
     MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
     return false;
   }
 
-  if (recordreplay::IsRecordingOrReplaying()) {
-    recordreplay::child::WaitForPaintToComplete();
-  }
-
   if (startTime) {
     mPaintTiming.sendMs() = (TimeStamp::Now() - startTime.value()).ToMilliseconds();
     mShadowManager->SendRecordPaintTimes(mPaintTiming);
   }
 
+  // Create a record/replay checkpoint after each paint.
+  if (recordreplay::IsRecordingOrReplaying()) {
+    recordreplay::child::CreateCheckpoint();
+  }
+
   *aSent = true;
   mIsFirstPaint = false;
   mFocusTarget = FocusTarget();
   MOZ_LAYERS_LOG(("[LayersForwarder] ... done"));
   return true;
 }
 
 RefPtr<CompositableClient>
--- a/layout/ipc/VsyncChild.cpp
+++ b/layout/ipc/VsyncChild.cpp
@@ -62,24 +62,22 @@ VsyncChild::ActorDestroy(ActorDestroyRea
 }
 
 mozilla::ipc::IPCResult
 VsyncChild::RecvNotify(const TimeStamp& aVsyncTimestamp)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mIsShutdown);
 
-  // Ignore Vsync messages sent to a recording/replaying process. Vsyncs are
-  // triggered at the top of the main thread's event loop instead.
-  if (recordreplay::IsRecordingOrReplaying()) {
-    return IPC_OK();
-  }
-
   SchedulerGroup::MarkVsyncRan();
   if (mObservingVsync && mObserver) {
+    if (recordreplay::IsRecordingOrReplaying()) {
+      recordreplay::child::OnVsync();
+    }
+
     mObserver->NotifyVsync(aVsyncTimestamp);
   }
   return IPC_OK();
 }
 
 void
 VsyncChild::SetVsyncObserver(VsyncObserver* aVsyncObserver)
 {
--- a/xpcom/threads/nsThread.cpp
+++ b/xpcom/threads/nsThread.cpp
@@ -1118,23 +1118,16 @@ nsThread::ProcessNextEvent(bool aMayWait
 
   LOG(("THRD(%p) ProcessNextEvent [%u %u]\n", this, aMayWait,
        mNestedEventLoopDepth));
 
   if (NS_WARN_IF(PR_GetCurrentThread() != mThread)) {
     return NS_ERROR_NOT_SAME_THREAD;
   }
 
-  // When recording or replaying, vsync observers are notified whenever
-  // processing events on the main thread. Waiting for explicit vsync messages
-  // from the UI process can result in paints happening at unexpected times.
-  if (recordreplay::IsRecordingOrReplaying() && mIsMainThread == MAIN_THREAD) {
-    recordreplay::child::NotifyVsyncObserver();
-  }
-
   // The toplevel event loop normally blocks waiting for the next event, but
   // if we're trying to shut this thread down, we must exit the event loop when
   // the event queue is empty.
   // This only applys to the toplevel event loop! Nested event loops (e.g.
   // during sync dispatch) are waiting for some state change and must be able
   // to block even if something has requested shutdown of the thread. Otherwise
   // we'll just busywait as we endlessly look for an event, fail to find one,
   // and repeat the nested event loop since its state change hasn't happened yet.