зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1323328 - Part 3: Add VR display request present mochitest; r=kip
MozReview-Commit-ID: 13WuFhUFcTo --HG-- extra : rebase_source : 00d5c0f36f3550c19367c4a9b6882c10175a0862
This commit is contained in:
Родитель
cfca85c8aa
Коммит
d7b6a3ff79
|
@ -27,3 +27,5 @@ FINAL_LIBRARY = 'xul'
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
'/dom/base'
|
'/dom/base'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
|
|
@ -0,0 +1,45 @@
|
||||||
|
|
||||||
|
var VRServiceTest;
|
||||||
|
|
||||||
|
var VRSimulationDriver = (function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var AttachWebVRDisplay = function() {
|
||||||
|
return VRServiceTest.attachVRDisplay("VRDisplayTest");
|
||||||
|
};
|
||||||
|
|
||||||
|
var SetVRDisplayPose = function(vrDisplay, position,
|
||||||
|
linearVelocity, linearAcceleration,
|
||||||
|
orientation, angularVelocity,
|
||||||
|
angularAcceleration) {
|
||||||
|
vrDisplay.setPose(position, linearVelocity, linearAcceleration,
|
||||||
|
orientation, angularVelocity, angularAcceleration);
|
||||||
|
};
|
||||||
|
|
||||||
|
var SetEyeResolution = function(width, height) {
|
||||||
|
vrDisplay.setEyeResolution(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
var SetEyeParameter = function(vrDisplay, eye, offsetX, offsetY, offsetZ,
|
||||||
|
upDegree, rightDegree, downDegree, leftDegree) {
|
||||||
|
vrDisplay.setEyeParameter(eye, offsetX, offsetY, offsetZ, upDegree, rightDegree,
|
||||||
|
downDegree, leftDegree);
|
||||||
|
}
|
||||||
|
|
||||||
|
var UpdateVRDisplay = function(vrDisplay) {
|
||||||
|
vrDisplay.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
var API = {
|
||||||
|
AttachWebVRDisplay: AttachWebVRDisplay,
|
||||||
|
SetVRDisplayPose: SetVRDisplayPose,
|
||||||
|
SetEyeResolution: SetEyeResolution,
|
||||||
|
SetEyeParameter: SetEyeParameter,
|
||||||
|
UpdateVRDisplay: UpdateVRDisplay,
|
||||||
|
|
||||||
|
none: false
|
||||||
|
};
|
||||||
|
|
||||||
|
return API;
|
||||||
|
|
||||||
|
}());
|
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
var WebVRHelpers = (function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var RequestPresentOnVRDisplay = function(vrDisplay, vrLayers, callback) {
|
||||||
|
if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
return vrDisplay.requestPresent(vrLayers);
|
||||||
|
};
|
||||||
|
|
||||||
|
var API = {
|
||||||
|
RequestPresentOnVRDisplay: RequestPresentOnVRDisplay,
|
||||||
|
|
||||||
|
none: false
|
||||||
|
};
|
||||||
|
|
||||||
|
return API;
|
||||||
|
|
||||||
|
}());
|
|
@ -0,0 +1,9 @@
|
||||||
|
[DEFAULT]
|
||||||
|
support-files =
|
||||||
|
VRSimulationDriver.js
|
||||||
|
requestPresent.js
|
||||||
|
runVRTest.js
|
||||||
|
WebVRHelpers.js
|
||||||
|
|
||||||
|
[test_vrDisplay_requestPresent.html]
|
||||||
|
skip-if = true
|
|
@ -0,0 +1,34 @@
|
||||||
|
// requestPresent.js
|
||||||
|
//
|
||||||
|
// This file provides helpers for testing VRDisplay requestPresent.
|
||||||
|
|
||||||
|
function setupVRDisplay(test) {
|
||||||
|
assert_equals(typeof (navigator.getVRDisplays), "function", "'navigator.getVRDisplays()' must be defined.");
|
||||||
|
return VRSimulationDriver.AttachWebVRDisplay().then(() => {
|
||||||
|
return navigator.getVRDisplays();
|
||||||
|
}).then((displays) => {
|
||||||
|
assert_equals(displays.length, 1, "displays.length must be one after attach.");
|
||||||
|
vrDisplay = displays[0];
|
||||||
|
return validateNewVRDisplay(test, vrDisplay);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the settings off a freshly created VRDisplay (prior to calling
|
||||||
|
// requestPresent).
|
||||||
|
function validateNewVRDisplay(test, display) {
|
||||||
|
assert_true(display.capabilities.canPresent, "display.capabilities.canPresent must always be true for HMDs.");
|
||||||
|
assert_equals(display.capabilities.maxLayers, 1, "display.capabilities.maxLayers must always be 1 when display.capabilities.canPresent is true for current spec revision.");
|
||||||
|
assert_false(display.isPresenting, "display.isPresenting must be false before calling requestPresent.");
|
||||||
|
assert_equals(display.getLayers().length, 0, "display.getLayers() should have no layers if not presenting.");
|
||||||
|
var promise = display.exitPresent();
|
||||||
|
return promise_rejects(test, null, promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the settings off a VRDisplay after requestPresent promise is
|
||||||
|
// rejected or after exitPresent is fulfilled.
|
||||||
|
function validateDisplayNotPresenting(test, display) {
|
||||||
|
assert_false(display.isPresenting, "display.isPresenting must be false if requestPresent is rejected or after exitPresent is fulfilled.");
|
||||||
|
assert_equals(display.getLayers().length, 0, "display.getLayers() should have no layers if requestPresent is rejected or after exitPresent is fulfilled.");
|
||||||
|
var promise = display.exitPresent();
|
||||||
|
return promise_rejects(test, null, promise);
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
function runVRTest(callback) {
|
||||||
|
SpecialPowers.pushPrefEnv({"set" : [["dom.vr.enabled", true],
|
||||||
|
["dom.vr.puppet.enabled", true],
|
||||||
|
["dom.vr.test.enabled", true]]},
|
||||||
|
() => {
|
||||||
|
VRServiceTest = navigator.requestVRServiceTest();
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>VRDisplay RequestPresent</title>
|
||||||
|
<meta name="timeout" content="long"/>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="VRSimulationDriver.js"></script>
|
||||||
|
<script src="WebVRHelpers.js"></script>
|
||||||
|
<script src="requestPresent.js"></script>
|
||||||
|
<script src="runVRTest.js"></script>
|
||||||
|
</head>
|
||||||
|
<body id="body">
|
||||||
|
<canvas id="webglCanvas"></canvas>
|
||||||
|
<div id="testDiv"></div>
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
var vrDisplay;
|
||||||
|
var canvas = document.getElementById('webglCanvas');
|
||||||
|
var div = document.getElementById('testDiv');
|
||||||
|
function startTest() {
|
||||||
|
promise_test((test) => {
|
||||||
|
return setupVRDisplay(test).then(() => {
|
||||||
|
return promise_rejects(test, null, WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{}]));
|
||||||
|
}).then(() => {
|
||||||
|
return validateDisplayNotPresenting(test, vrDisplay);
|
||||||
|
});
|
||||||
|
}, "WebVR requestPresent rejected with empty frames");
|
||||||
|
|
||||||
|
promise_test((test) => {
|
||||||
|
return setupVRDisplay(test).then(() => {
|
||||||
|
return promise_rejects(test, null, WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: canvas, leftBounds: [0.0, 0.0] }]));
|
||||||
|
}).then(() => {
|
||||||
|
return validateDisplayNotPresenting(test, vrDisplay);
|
||||||
|
});
|
||||||
|
}, "WebVR requestPresent rejected with incorrect bounds (bounds arrays must be 0 or 4 long)");
|
||||||
|
|
||||||
|
promise_test((test) => {
|
||||||
|
return setupVRDisplay(test).then(() => {
|
||||||
|
return promise_rejects(test, null, WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: div }]));
|
||||||
|
}).then(() => {
|
||||||
|
return validateDisplayNotPresenting(test, vrDisplay);
|
||||||
|
});
|
||||||
|
}, "WebVR requestPresent rejected with invalid source (must be canvas element)");
|
||||||
|
|
||||||
|
promise_test((test) => {
|
||||||
|
return setupVRDisplay(test).then(() => {
|
||||||
|
return promise_rejects(test, null, WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: canvas, leftBounds: [div] }]));
|
||||||
|
}).then(() => {
|
||||||
|
return validateDisplayNotPresenting(test, vrDisplay);
|
||||||
|
});
|
||||||
|
}, "WebVR requestPresent rejected with invalid bounds data type (must be able to convert to float)");
|
||||||
|
|
||||||
|
const invalidBounds = [
|
||||||
|
[2.0, 0.0, 0.0, 0.0],
|
||||||
|
[0.0, 2.0, 0.0, 0.0],
|
||||||
|
[0.0, 0.0, 2.0, 0.0],
|
||||||
|
[0.0, 0.0, 0.0, 2.0],
|
||||||
|
[-1.0, 0.0, 0.0, 0.0],
|
||||||
|
[0.0, -1.0, 0.0, 0.0],
|
||||||
|
[0.0, 0.0, -1.0, 0.0],
|
||||||
|
[0.0, 0.0, 0.0, -1.0]];
|
||||||
|
|
||||||
|
invalidBounds.forEach((bound) => {
|
||||||
|
promise_test((test) => {
|
||||||
|
return setupVRDisplay(test).then(() => {
|
||||||
|
return promise_rejects(test, null, WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: canvas, leftBounds: bound }]));
|
||||||
|
}).then(() => {
|
||||||
|
return validateDisplayNotPresenting(test, vrDisplay);
|
||||||
|
});
|
||||||
|
}, "WebVR requestPresent rejected with bounds in invalid range: [" + bound + "]");
|
||||||
|
});
|
||||||
|
|
||||||
|
promise_test((test) => {
|
||||||
|
return setupVRDisplay(test).then(() => {
|
||||||
|
var promise = vrDisplay.requestPresent({ source: canvas });
|
||||||
|
return promise_rejects(test, null, promise);
|
||||||
|
}).then(() => {
|
||||||
|
return validateDisplayNotPresenting(test, vrDisplay);
|
||||||
|
});
|
||||||
|
}, "WebVR requestPresent rejected without user initiated action");
|
||||||
|
|
||||||
|
promise_test((test) => {
|
||||||
|
return setupVRDisplay(test).then(() => {
|
||||||
|
return promise_rejects(test, null, WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: canvas }, { source: canvas }]));
|
||||||
|
}).then(() => {
|
||||||
|
return validateDisplayNotPresenting(test, vrDisplay);
|
||||||
|
});
|
||||||
|
}, "WebVR requestPresent rejected with more frames than max layers");
|
||||||
|
|
||||||
|
promise_test((test) => {
|
||||||
|
return setupVRDisplay(test).then(() => {
|
||||||
|
function requestAgain() {
|
||||||
|
// Callback for immediate requestPresent call for further testing.
|
||||||
|
// Cache this promise on global object since it seems to be the only object
|
||||||
|
// in scope across calls.
|
||||||
|
window.promiseSecond = vrDisplay.requestPresent([{ source: canvas }]);
|
||||||
|
}
|
||||||
|
return WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: canvas }], requestAgain);
|
||||||
|
}).then(() => {
|
||||||
|
// First promise succeeded
|
||||||
|
assert_true(vrDisplay.isPresenting, "First promise should successfully fulfill");
|
||||||
|
// Now, validate that the subsequent requestPresent was rejected
|
||||||
|
return promise_rejects(test, null, window.promiseSecond);
|
||||||
|
}).then(() => {
|
||||||
|
delete window.promiseSecond;
|
||||||
|
assert_true(vrDisplay.isPresenting, "Should still be presenting after rejected second promise");
|
||||||
|
return vrDisplay.exitPresent();
|
||||||
|
});
|
||||||
|
}, "WebVR requestPresent fails while another one is in progress");
|
||||||
|
|
||||||
|
promise_test((test) => {
|
||||||
|
return setupVRDisplay(test).then(() => {
|
||||||
|
return WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: canvas }]);
|
||||||
|
}).then(() => {
|
||||||
|
assert_true(vrDisplay.isPresenting, "vrDisplay.isPresenting must be true if requestPresent is fulfilled.");
|
||||||
|
assert_equals(vrDisplay.getLayers().length, 1, "vrDisplay.getLayers() should return one layer.");
|
||||||
|
return vrDisplay.exitPresent();
|
||||||
|
}).then(() => {
|
||||||
|
assert_false(vrDisplay.isPresenting, "vrDisplay.isPresenting must be false if exitPresent is fulfilled.");
|
||||||
|
// exitPresent() should reject since we are no longer presenting.
|
||||||
|
return promise_rejects(test, null, vrDisplay.exitPresent());
|
||||||
|
});
|
||||||
|
}, "WebVR requestPresent fulfilled");
|
||||||
|
}
|
||||||
|
|
||||||
|
runVRTest(startTest);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -5036,6 +5036,8 @@ pref("gfx.vr.osvr.utilLibPath", "");
|
||||||
pref("gfx.vr.osvr.commonLibPath", "");
|
pref("gfx.vr.osvr.commonLibPath", "");
|
||||||
pref("gfx.vr.osvr.clientLibPath", "");
|
pref("gfx.vr.osvr.clientLibPath", "");
|
||||||
pref("gfx.vr.osvr.clientKitLibPath", "");
|
pref("gfx.vr.osvr.clientKitLibPath", "");
|
||||||
|
// Puppet device, used for simulating VR hardware within tests and dev tools
|
||||||
|
pref("dom.vr.puppet.enabled", false);
|
||||||
pref("dom.vr.test.enabled", false);
|
pref("dom.vr.test.enabled", false);
|
||||||
// MMS UA Profile settings
|
// MMS UA Profile settings
|
||||||
pref("wap.UAProf.url", "");
|
pref("wap.UAProf.url", "");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче