зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1708070 - Use VsyncTaskManager::WillRunTask to change InputVsyncState r=smaug
Currently, we use `VsyncTaskManager::DidRunTask` to change state from `RunVsync` to `NoPendingVsync`, however, the issue is that if the vsync starts an event loop (for instance, by using requestAnimationFrame), and the event loop starts another input task, Firefox crashes because input tasks don't expect the state to be `RunVsync`. So instead of using `DidRunTask`, we start to use `WillRunTask` to fix it. Differential Revision: https://phabricator.services.mozilla.com/D113613
This commit is contained in:
Родитель
4fab3e6602
Коммит
53d05dfbc0
|
@ -243,6 +243,7 @@ support-files =
|
|||
!/dom/events/test/event_leak_utils.js
|
||||
../../../toolkit/components/pdfjs/test/file_pdfjs_test.pdf
|
||||
green.png
|
||||
slow.sjs
|
||||
|
||||
[test_anchor_area_referrer.html]
|
||||
[test_anchor_area_referrer_changing.html]
|
||||
|
@ -683,6 +684,7 @@ skip-if = (processor == 'aarch64' && os == 'win') # aarch64 due to 1530895
|
|||
[test_innersize_scrollport.html]
|
||||
skip-if = (verify && (os == 'win' || os == 'mac'))
|
||||
[test_input_vsync_alignment_lower_than_normal.html]
|
||||
[test_input_vsync_alignment_input_while_vsync.html]
|
||||
[test_integer_attr_with_leading_zero.html]
|
||||
[test_intersectionobservers.html]
|
||||
[test_link_prefetch.html]
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
function handleRequest(request, response)
|
||||
{
|
||||
response.processAsync();
|
||||
|
||||
timer = Components.classes["@mozilla.org/timer;1"].
|
||||
createInstance(Components.interfaces.nsITimer);
|
||||
timer.init(function() {
|
||||
response.write("Here the content. But slowly.");
|
||||
response.finish();
|
||||
}, 5000, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
</head>
|
||||
<body >
|
||||
<input />
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function triggerKey() {
|
||||
SpecialPowers.loadChromeScript(() => {
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { EventUtils } = ChromeUtils.import(
|
||||
"resource://specialpowers/SpecialPowersEventUtils.jsm"
|
||||
);
|
||||
var win = Services.wm.getMostRecentBrowserWindow();
|
||||
for (let i = 0; i < 200; ++i) {
|
||||
EventUtils.synthesizeKey("a", {}, win);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
const input = document.querySelector("input");
|
||||
input.focus();
|
||||
|
||||
let didInputRun = false;
|
||||
|
||||
input.addEventListener("input", function() {
|
||||
if (!didInputRun) {
|
||||
didInputRun = true;
|
||||
window.requestAnimationFrame(() => {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "slow.sjs", false);
|
||||
xhr.send();
|
||||
ok(true, "Didn't crash!");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
triggerKey();
|
||||
}
|
||||
runTest();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -143,7 +143,7 @@ void InputTaskManager::InputPriorityController::EnterPendingVsyncState(
|
|||
mRunInputStartTime = TimeStamp::Now();
|
||||
}
|
||||
|
||||
void InputTaskManager::InputPriorityController::DidVsync() {
|
||||
void InputTaskManager::InputPriorityController::WillRunVsync() {
|
||||
MOZ_ASSERT(StaticPrefs::dom_input_events_strict_input_vsync_alignment());
|
||||
|
||||
if (mInputVsyncState == InputVsyncState::RunVsync ||
|
||||
|
|
|
@ -84,7 +84,7 @@ class InputTaskManager : public TaskManager {
|
|||
|
||||
void NotifyVsync() {
|
||||
MOZ_ASSERT(StaticPrefs::dom_input_events_strict_input_vsync_alignment());
|
||||
mInputPriorityController.DidVsync();
|
||||
mInputPriorityController.WillRunVsync();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -97,7 +97,7 @@ class InputTaskManager : public TaskManager {
|
|||
// tasks
|
||||
bool ShouldUseHighestPriority(InputTaskManager*);
|
||||
|
||||
void DidVsync();
|
||||
void WillRunVsync();
|
||||
|
||||
// Gets called when a input task is finished to run; If the current
|
||||
// input vsync state is `HasPendingVsync`, determines whether we
|
||||
|
|
|
@ -15,8 +15,8 @@ void VsyncTaskManager::Init() {
|
|||
gHighPriorityTaskManager = new VsyncTaskManager();
|
||||
}
|
||||
|
||||
void VsyncTaskManager::DidRunTask() {
|
||||
TaskManager::DidRunTask();
|
||||
void VsyncTaskManager::WillRunTask() {
|
||||
TaskManager::WillRunTask();
|
||||
|
||||
if (StaticPrefs::dom_input_events_strict_input_vsync_alignment()) {
|
||||
InputTaskManager::Get()->NotifyVsync();
|
||||
|
|
|
@ -16,7 +16,7 @@ class VsyncTaskManager : public TaskManager {
|
|||
static void Cleanup() { gHighPriorityTaskManager = nullptr; }
|
||||
static void Init();
|
||||
|
||||
void DidRunTask() override;
|
||||
void WillRunTask() override;
|
||||
|
||||
private:
|
||||
static StaticRefPtr<VsyncTaskManager> gHighPriorityTaskManager;
|
||||
|
|
Загрузка…
Ссылка в новой задаче