зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1503750 - Add preference to allow crashing on repaint failures, r=mccr8.
--HG-- extra : rebase_source : df926fba3f291e2a56975936d1090c7d0ce54c60
This commit is contained in:
Родитель
579aa6d5df
Коммит
e3503a74b9
|
@ -1110,6 +1110,7 @@ pref("devtools.recordreplay.enableRewinding", true);
|
|||
|
||||
pref("devtools.recordreplay.mvp.enabled", false);
|
||||
pref("devtools.recordreplay.timeline.enabled", false);
|
||||
pref("devtools.recordreplay.allowRepaintFailures", true);
|
||||
|
||||
// view source
|
||||
pref("view_source.syntax_highlight", true);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "InfallibleVector.h"
|
||||
#include "MiddlemanCall.h"
|
||||
#include "ipc/ChildInternal.h"
|
||||
#include "ipc/ParentInternal.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
|
@ -100,9 +101,11 @@ RecordReplayInterceptCall(int aCallId, CallArguments* aArguments)
|
|||
}
|
||||
}
|
||||
|
||||
if (parent::InRepaintStressMode()) {
|
||||
// We're about to crash, so print out the name of the call that failed.
|
||||
Print("Could not perform middleman call: %s\n", redirection.mName);
|
||||
if (child::CurrentRepaintCannotFail()) {
|
||||
// EnsureNotDivergedFromRecording is going to force us to crash, so fail
|
||||
// earlier with a more helpful error message.
|
||||
child::ReportFatalError(Nothing(), "Could not perform middleman call: %s\n",
|
||||
redirection.mName);
|
||||
}
|
||||
|
||||
// Calling any redirection which performs the standard steps will cause
|
||||
|
|
|
@ -237,10 +237,10 @@ EnsureNotDivergedFromRecording()
|
|||
if (HasDivergedFromRecording()) {
|
||||
MOZ_RELEASE_ASSERT(gUnhandledDivergeAllowed);
|
||||
|
||||
// Crash instead of rewinding in the painting stress mode, for finding
|
||||
// areas where middleman calls do not cover all painting logic.
|
||||
if (parent::InRepaintStressMode()) {
|
||||
MOZ_CRASH("Recording divergence in repaint stress mode");
|
||||
// Crash instead of rewinding if a repaint is about to fail and is not
|
||||
// allowed.
|
||||
if (child::CurrentRepaintCannotFail()) {
|
||||
MOZ_CRASH("Recording divergence while repainting");
|
||||
}
|
||||
|
||||
PrintSpew("Unhandled recording divergence, restoring checkpoint...\n");
|
||||
|
|
|
@ -475,6 +475,9 @@ static Atomic<int32_t, SequentiallyConsistent, Behavior::DontPreserve> gNumPendi
|
|||
// ID of the compositor thread.
|
||||
static Atomic<size_t, SequentiallyConsistent, Behavior::DontPreserve> gCompositorThreadId;
|
||||
|
||||
// Whether repaint failures are allowed, or if the process should crash.
|
||||
static bool gAllowRepaintFailures;
|
||||
|
||||
already_AddRefed<gfx::DrawTarget>
|
||||
DrawTargetForRemoteDrawing(LayoutDeviceIntSize aSize)
|
||||
{
|
||||
|
@ -522,6 +525,17 @@ NotifyPaintStart()
|
|||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Initialize state on the first paint.
|
||||
static bool gPainted;
|
||||
if (!gPainted) {
|
||||
gPainted = true;
|
||||
|
||||
// Repaint failures are not allowed in the repaint stress mode.
|
||||
gAllowRepaintFailures =
|
||||
Preferences::GetBool("devtools.recordreplay.allowRepaintFailures") &&
|
||||
!parent::InRepaintStressMode();
|
||||
}
|
||||
|
||||
// A new paint cannot be triggered until the last one finishes and has been
|
||||
// sent to the middleman.
|
||||
MOZ_RELEASE_ASSERT(HasDivergedFromRecording() || !gHasActivePaint);
|
||||
|
@ -571,6 +585,9 @@ NotifyPaintComplete()
|
|||
// Whether we have repainted since diverging from the recording.
|
||||
static bool gDidRepaint;
|
||||
|
||||
// Whether we are currently repainting.
|
||||
static bool gRepainting;
|
||||
|
||||
void
|
||||
Repaint(size_t* aWidth, size_t* aHeight)
|
||||
{
|
||||
|
@ -588,6 +605,7 @@ Repaint(size_t* aWidth, size_t* aHeight)
|
|||
// case the last graphics we sent will still be correct.
|
||||
if (!gDidRepaint) {
|
||||
gDidRepaint = true;
|
||||
gRepainting = true;
|
||||
|
||||
// Allow other threads to diverge from the recording so the compositor can
|
||||
// perform any paint we are about to trigger, or finish any in flight paint
|
||||
|
@ -611,6 +629,7 @@ Repaint(size_t* aWidth, size_t* aHeight)
|
|||
}
|
||||
|
||||
Thread::WaitForIdleThreads();
|
||||
gRepainting = false;
|
||||
}
|
||||
|
||||
if (gDrawTargetBuffer) {
|
||||
|
@ -623,6 +642,12 @@ Repaint(size_t* aWidth, size_t* aHeight)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CurrentRepaintCannotFail()
|
||||
{
|
||||
return gRepainting && !gAllowRepaintFailures;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Checkpoint Messages
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -115,9 +115,6 @@ void NotifyFlushedRecording();
|
|||
// Notify the middleman about an AlwaysMarkMajorCheckpoints directive.
|
||||
void NotifyAlwaysMarkMajorCheckpoints();
|
||||
|
||||
// Report a fatal error to the middleman process.
|
||||
void ReportFatalError(const char* aFormat, ...);
|
||||
|
||||
// Mark a time span when the main thread is idle.
|
||||
void BeginIdleTime();
|
||||
void EndIdleTime();
|
||||
|
@ -130,6 +127,10 @@ void SendMiddlemanCallRequest(const char* aInputData, size_t aInputSize,
|
|||
InfallibleVector<char>* aOutputData);
|
||||
void SendResetMiddlemanCalls();
|
||||
|
||||
// Return whether a repaint is in progress and is not allowed to trigger an
|
||||
// unhandled recording divergence per preferences.
|
||||
bool CurrentRepaintCannotFail();
|
||||
|
||||
} // namespace child
|
||||
|
||||
} // namespace recordreplay
|
||||
|
|
Загрузка…
Ссылка в новой задаче