зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1018862
part 8 - Add special handling for non-invertible transforms; r=dholbert
This patch adjusts the tests for transform transitions that run on the compositor to handle transitions that begin with a non-invertible transform. In this case the first sample at the start of the animation won't create a layer because in nsDisplayTransform::BuildLayer / FrameLayerBuilder::BuildContainerLayerFor we'll skip creating the layer once we notice the equivalent matrix is singular. In this patch we detect that case and force an extra sample betwee 0 and 200s at 100s. This means the layer will be created at t=100s and be available for querying at the next sample. Similar issues could occur, for example, if the transforms at both t=0s and t=100s are not invertible but currently that doesn't occur. We can add handling for that if and when it becomes necessary.
This commit is contained in:
Родитель
d73c4f0840
Коммит
da8fce7eea
|
@ -398,7 +398,7 @@ const ExpectComparisonTo = {
|
|||
// "matrix3d(...)"
|
||||
// [ 1, 0, 0, ... ]
|
||||
// { a: 1, ty: 23 } etc.
|
||||
function convertTo3dMatrix(matrixLike) {
|
||||
window.convertTo3dMatrix = function(matrixLike) {
|
||||
if (typeof(matrixLike) == "string") {
|
||||
return convertStringTo3dMatrix(matrixLike);
|
||||
} else if (Array.isArray(matrixLike)) {
|
||||
|
@ -408,7 +408,13 @@ const ExpectComparisonTo = {
|
|||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// In future most of these methods should be able to be replaced
|
||||
// with DOMMatrix
|
||||
window.isInvertible = function(matrix) {
|
||||
return getDeterminant(matrix) != 0;
|
||||
};
|
||||
|
||||
// Converts strings of the format "matrix(...)" and "matrix3d(...)" to a 3d
|
||||
// matrix
|
||||
|
@ -498,6 +504,37 @@ const ExpectComparisonTo = {
|
|||
matrix[2][2] === 1 && matrix[2][3] === 0 &&
|
||||
matrix[3][2] === 0 && matrix[3][3] === 1;
|
||||
}
|
||||
|
||||
function getDeterminant(matrix) {
|
||||
if (is2d(matrix)) {
|
||||
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
|
||||
}
|
||||
|
||||
return matrix[0][3] * matrix[1][2] * matrix[2][1] * matrix[3][0]
|
||||
- matrix[0][2] * matrix[1][3] * matrix[2][1] * matrix[3][0]
|
||||
- matrix[0][3] * matrix[1][1] * matrix[2][2] * matrix[3][0]
|
||||
+ matrix[0][1] * matrix[1][3] * matrix[2][2] * matrix[3][0]
|
||||
+ matrix[0][2] * matrix[1][1] * matrix[2][3] * matrix[3][0]
|
||||
- matrix[0][1] * matrix[1][2] * matrix[2][3] * matrix[3][0]
|
||||
- matrix[0][3] * matrix[1][2] * matrix[2][0] * matrix[3][1]
|
||||
+ matrix[0][2] * matrix[1][3] * matrix[2][0] * matrix[3][1]
|
||||
+ matrix[0][3] * matrix[1][0] * matrix[2][2] * matrix[3][1]
|
||||
- matrix[0][0] * matrix[1][3] * matrix[2][2] * matrix[3][1]
|
||||
- matrix[0][2] * matrix[1][0] * matrix[2][3] * matrix[3][1]
|
||||
+ matrix[0][0] * matrix[1][2] * matrix[2][3] * matrix[3][1]
|
||||
+ matrix[0][3] * matrix[1][1] * matrix[2][0] * matrix[3][2]
|
||||
- matrix[0][1] * matrix[1][3] * matrix[2][0] * matrix[3][2]
|
||||
- matrix[0][3] * matrix[1][0] * matrix[2][1] * matrix[3][2]
|
||||
+ matrix[0][0] * matrix[1][3] * matrix[2][1] * matrix[3][2]
|
||||
+ matrix[0][1] * matrix[1][0] * matrix[2][3] * matrix[3][2]
|
||||
- matrix[0][0] * matrix[1][1] * matrix[2][3] * matrix[3][2]
|
||||
- matrix[0][2] * matrix[1][1] * matrix[2][0] * matrix[3][3]
|
||||
+ matrix[0][1] * matrix[1][2] * matrix[2][0] * matrix[3][3]
|
||||
+ matrix[0][2] * matrix[1][0] * matrix[2][1] * matrix[3][3]
|
||||
- matrix[0][0] * matrix[1][2] * matrix[2][1] * matrix[3][3]
|
||||
- matrix[0][1] * matrix[1][0] * matrix[2][2] * matrix[3][3]
|
||||
+ matrix[0][0] * matrix[1][1] * matrix[2][2] * matrix[3][3];
|
||||
}
|
||||
})();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -1955,11 +1955,6 @@ function addAsyncTransformTests() {
|
|||
}
|
||||
|
||||
function *runTransformTest(test) {
|
||||
// Skip the following test for now.
|
||||
// We'll work around this properly in a subsequent patch in this queue.
|
||||
if (test.start == "skew(45deg, 45deg)")
|
||||
return;
|
||||
|
||||
OMTAdiv.style.setProperty("transition-property", "none", "");
|
||||
OMTAdiv.style.setProperty("transform", test.start, "");
|
||||
OMTACs.getPropertyValue("transform");
|
||||
|
@ -1968,7 +1963,17 @@ function *runTransformTest(test) {
|
|||
OMTACs.getPropertyValue("transform");
|
||||
yield waitForPaints();
|
||||
|
||||
winUtils.advanceTimeAndRefresh(200000);
|
||||
// If the start value produced a non-invertible matrix the layer won't be
|
||||
// created yet so we need to force an extra sample.
|
||||
if (!isTransformInvertible(test.start)) {
|
||||
winUtils.advanceTimeAndRefresh(100000);
|
||||
yield waitForPaints();
|
||||
winUtils.advanceTimeAndRefresh(100000);
|
||||
yield waitForPaints();
|
||||
} else {
|
||||
winUtils.advanceTimeAndRefresh(200000);
|
||||
yield waitForPaints();
|
||||
}
|
||||
|
||||
omta_is_approx(OMTAdiv, "transform", OMTACs.getPropertyValue("transform"),
|
||||
0.0001, RunningOn.Compositor,
|
||||
|
@ -1997,6 +2002,22 @@ function addAsyncOpacityTest() {
|
|||
OMTAdiv.style.removeProperty("transition");
|
||||
});
|
||||
}
|
||||
|
||||
function isTransformInvertible(transformStr) {
|
||||
var computedStr = transformStrToComputedStr(transformStr);
|
||||
if (!transformStr)
|
||||
return false;
|
||||
var matrix = convertTo3dMatrix(computedStr);
|
||||
if (matrix === null)
|
||||
return false;
|
||||
return isInvertible(matrix);
|
||||
}
|
||||
|
||||
function transformStrToComputedStr(transformStr) {
|
||||
var div = document.createElement("div");
|
||||
div.style.transform = transformStr;
|
||||
return window.getComputedStyle(div).transform;
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
Загрузка…
Ссылка в новой задаче