зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1250718 - Don't flatten opacity to an intermediate surface when used in the middle of preserve-3d. r=thinker
--HG-- extra : rebase_source : 867bab1b5369c88db3a845478f73d3a58845938c
This commit is contained in:
Родитель
8d2b64d662
Коммит
dbe7f4888a
|
@ -1387,10 +1387,17 @@ ContainerLayer::DefaultComputeEffectiveTransforms(const Matrix4x4& aTransformToS
|
|||
useIntermediateSurface = true;
|
||||
#endif
|
||||
} else {
|
||||
/* Don't use an intermediate surface for opacity when it's within a 3d
|
||||
* context, since we'd rather keep the 3d effects. This matches the
|
||||
* WebKit/blink behaviour, but is changing in the latest spec.
|
||||
*/
|
||||
float opacity = GetEffectiveOpacity();
|
||||
CompositionOp blendMode = GetEffectiveMixBlendMode();
|
||||
if (((opacity != 1.0f || blendMode != CompositionOp::OP_OVER) && (HasMultipleChildren() || Creates3DContextWithExtendingChildren())) ||
|
||||
(!idealTransform.Is2D() && Creates3DContextWithExtendingChildren())) {
|
||||
if ((HasMultipleChildren() || Creates3DContextWithExtendingChildren()) &&
|
||||
((opacity != 1.0f && !Extend3DContext()) ||
|
||||
(blendMode != CompositionOp::OP_OVER))) {
|
||||
useIntermediateSurface = true;
|
||||
} else if (!idealTransform.Is2D() && Creates3DContextWithExtendingChildren()) {
|
||||
useIntermediateSurface = true;
|
||||
} else {
|
||||
useIntermediateSurface = false;
|
||||
|
|
|
@ -83,7 +83,7 @@ BasicContainerLayer::ComputeEffectiveTransforms(const Matrix4x4& aTransformToSur
|
|||
GetMaskLayer() ||
|
||||
GetForceIsolatedGroup() ||
|
||||
(GetMixBlendMode() != CompositionOp::OP_OVER && HasMultipleChildren()) ||
|
||||
(GetEffectiveOpacity() != 1.0 && (HasMultipleChildren() || hasSingleBlendingChild));
|
||||
(GetEffectiveOpacity() != 1.0 && ((HasMultipleChildren() && !Extend3DContext()) || hasSingleBlendingChild));
|
||||
|
||||
if (!Extend3DContext()) {
|
||||
idealTransform.ProjectTo2D();
|
||||
|
|
|
@ -2003,7 +2003,8 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
|||
bool same3DContext =
|
||||
(itemType == nsDisplayItem::TYPE_TRANSFORM &&
|
||||
static_cast<nsDisplayTransform*>(item)->IsParticipating3DContext()) ||
|
||||
(itemType == nsDisplayItem::TYPE_PERSPECTIVE &&
|
||||
((itemType == nsDisplayItem::TYPE_PERSPECTIVE ||
|
||||
itemType == nsDisplayItem::TYPE_OPACITY) &&
|
||||
static_cast<nsDisplayPerspective*>(item)->Frame()->Extend3DContext());
|
||||
if (same3DContext &&
|
||||
!static_cast<nsDisplayTransform*>(item)->IsLeafOf3DContext()) {
|
||||
|
@ -4152,6 +4153,7 @@ nsDisplayOpacity::nsDisplayOpacity(nsDisplayListBuilder* aBuilder,
|
|||
: nsDisplayWrapList(aBuilder, aFrame, aList, aScrollClip)
|
||||
, mOpacity(aFrame->StyleDisplay()->mOpacity)
|
||||
, mForEventsOnly(aForEventsOnly)
|
||||
, mParticipatesInPreserve3D(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayOpacity);
|
||||
}
|
||||
|
@ -4189,6 +4191,12 @@ nsDisplayOpacity::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||
nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(container, aBuilder,
|
||||
this, mFrame,
|
||||
eCSSProperty_opacity);
|
||||
|
||||
if (mParticipatesInPreserve3D) {
|
||||
container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_EXTEND_3D_CONTEXT);
|
||||
} else {
|
||||
container->SetContentFlags(container->GetContentFlags() & ~Layer::CONTENT_EXTEND_3D_CONTEXT);
|
||||
}
|
||||
return container.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -3375,9 +3375,14 @@ public:
|
|||
|
||||
bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) override;
|
||||
|
||||
void SetParticipatesInPreserve3D(bool aParticipatesInPreserve3D)
|
||||
{
|
||||
mParticipatesInPreserve3D = aParticipatesInPreserve3D;
|
||||
}
|
||||
private:
|
||||
float mOpacity;
|
||||
bool mForEventsOnly;
|
||||
bool mParticipatesInPreserve3D;
|
||||
};
|
||||
|
||||
class nsDisplayBlendMode : public nsDisplayWrapList {
|
||||
|
|
|
@ -1159,12 +1159,6 @@ nsIFrame::Extend3DContext() const
|
|||
return false;
|
||||
}
|
||||
|
||||
// Opacity can only be only the root or leaves of a preserve-3d context
|
||||
// as it requires flattening.
|
||||
if (HasOpacity() && Combines3DTransformWithAncestors()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRect temp;
|
||||
return !nsFrame::ShouldApplyOverflowClipping(this, disp) &&
|
||||
!GetClipPropClipRect(disp, &temp, GetSize()) &&
|
||||
|
@ -1881,7 +1875,8 @@ static bool
|
|||
ItemParticipatesIn3DContext(nsIFrame* aAncestor, nsDisplayItem* aItem)
|
||||
{
|
||||
nsIFrame* transformFrame;
|
||||
if (aItem->GetType() == nsDisplayItem::TYPE_TRANSFORM) {
|
||||
if (aItem->GetType() == nsDisplayItem::TYPE_TRANSFORM ||
|
||||
aItem->GetType() == nsDisplayItem::TYPE_OPACITY) {
|
||||
transformFrame = aItem->Frame();
|
||||
} else if (aItem->GetType() == nsDisplayItem::TYPE_PERSPECTIVE) {
|
||||
transformFrame = static_cast<nsDisplayPerspective*>(aItem)->TransformFrame();
|
||||
|
@ -1911,16 +1906,21 @@ WrapSeparatorTransform(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
|||
static void
|
||||
CreateOpacityItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
nsDisplayList& aList, bool aItemForEventsOnly,
|
||||
const DisplayItemScrollClip* aScrollClip)
|
||||
const DisplayItemScrollClip* aScrollClip,
|
||||
bool aParticipatesInPreserve3D)
|
||||
{
|
||||
// Don't clip nsDisplayOpacity items. We clip their descendants instead.
|
||||
// The clip we would set on an element with opacity would clip
|
||||
// all descendant content, but some should not be clipped.
|
||||
DisplayListClipState::AutoSaveRestore opacityClipState(aBuilder);
|
||||
opacityClipState.Clear();
|
||||
aList.AppendNewToTop(
|
||||
nsDisplayOpacity* opacity =
|
||||
new (aBuilder) nsDisplayOpacity(aBuilder, aFrame, &aList,
|
||||
aScrollClip, aItemForEventsOnly));
|
||||
aScrollClip, aItemForEventsOnly);
|
||||
if (opacity) {
|
||||
opacity->SetParticipatesInPreserve3D(aParticipatesInPreserve3D);
|
||||
aList.AppendToTop(opacity);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2021,7 +2021,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
aBuilder->EnterSVGEffectsContents(&hoistedScrollInfoItemsStorage);
|
||||
}
|
||||
|
||||
bool useOpacity = HasVisualOpacity() && !nsSVGUtils::CanOptimizeOpacity(this);
|
||||
bool useOpacity = HasVisualOpacity() && !nsSVGUtils::CanOptimizeOpacity(this) && !usingSVGEffects;
|
||||
bool useBlendMode = disp->mMixBlendMode != NS_STYLE_BLEND_NORMAL;
|
||||
bool useStickyPosition = disp->mPosition == NS_STYLE_POSITION_STICKY &&
|
||||
IsScrollFrameActive(aBuilder,
|
||||
|
@ -2172,8 +2172,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
clipState.ExitStackingContextContents(&containerItemScrollClip);
|
||||
}
|
||||
|
||||
bool is3DContextRoot = Extend3DContext() && !Combines3DTransformWithAncestors();
|
||||
|
||||
/* If there are any SVG effects, wrap the list up in an SVG effects item
|
||||
* (which also handles CSS group opacity). Note that we create an SVG effects
|
||||
* item even if resultList is empty, since a filter can produce graphical
|
||||
|
@ -2190,18 +2188,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
aBuilder->ExitSVGEffectsContents();
|
||||
resultList.AppendToTop(&hoistedScrollInfoItemsStorage);
|
||||
}
|
||||
else if (useOpacity && !resultList.IsEmpty() && !is3DContextRoot) {
|
||||
/* If this element is the root of a preserve-3d context, then we want
|
||||
* to make sure any opacity items are on the outside of the transform
|
||||
* so that they don't interfere with the chain of nsDisplayTransforms.
|
||||
* Opacity on preserve-3d leaves need to be inside the transform for the
|
||||
* same reason, and we do this in the general case as well to preserve
|
||||
* existing behaviour.
|
||||
*/
|
||||
CreateOpacityItem(aBuilder, this, resultList, opacityItemForEventsOnly,
|
||||
containerItemScrollClip);
|
||||
useOpacity = false;
|
||||
}
|
||||
|
||||
/* If we're going to apply a transformation and don't have preserve-3d set, wrap
|
||||
* everything in an nsDisplayTransform. If there's nothing in the list, don't add
|
||||
|
@ -2214,36 +2200,49 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
* We also traverse into sublists created by nsDisplayWrapList or nsDisplayOpacity, so that
|
||||
* we find all the correct children.
|
||||
*/
|
||||
if (isTransformed && !resultList.IsEmpty()) {
|
||||
if (!resultList.IsEmpty() && Extend3DContext()) {
|
||||
// Install dummy nsDisplayTransform as a leaf containing
|
||||
// descendants not participating this 3D rendering context.
|
||||
nsDisplayList nonparticipants;
|
||||
nsDisplayList participants;
|
||||
int index = 1;
|
||||
bool hasPreserve3DChildren = false;
|
||||
if (isTransformed && !resultList.IsEmpty() && Extend3DContext()) {
|
||||
// Install dummy nsDisplayTransform as a leaf containing
|
||||
// descendants not participating this 3D rendering context.
|
||||
nsDisplayList nonparticipants;
|
||||
nsDisplayList participants;
|
||||
int index = 1;
|
||||
|
||||
while (nsDisplayItem* item = resultList.RemoveBottom()) {
|
||||
if (ItemParticipatesIn3DContext(this, item) && !item->GetClip().HasClip()) {
|
||||
// The frame of this item participates the same 3D context.
|
||||
WrapSeparatorTransform(aBuilder, this, dirtyRect,
|
||||
&nonparticipants, &participants, index++);
|
||||
participants.AppendToTop(item);
|
||||
} else {
|
||||
// The frame of the item doesn't participate the current
|
||||
// context, or has no transform.
|
||||
//
|
||||
// For items participating but not transformed, they are add
|
||||
// to nonparticipants to get a separator layer for handling
|
||||
// clips, if there is, on an intermediate surface.
|
||||
// \see ContainerLayer::DefaultComputeEffectiveTransforms().
|
||||
nonparticipants.AppendToTop(item);
|
||||
}
|
||||
while (nsDisplayItem* item = resultList.RemoveBottom()) {
|
||||
if (ItemParticipatesIn3DContext(this, item) && !item->GetClip().HasClip()) {
|
||||
// The frame of this item participates the same 3D context.
|
||||
WrapSeparatorTransform(aBuilder, this, dirtyRect,
|
||||
&nonparticipants, &participants, index++);
|
||||
participants.AppendToTop(item);
|
||||
hasPreserve3DChildren = true;
|
||||
} else {
|
||||
// The frame of the item doesn't participate the current
|
||||
// context, or has no transform.
|
||||
//
|
||||
// For items participating but not transformed, they are add
|
||||
// to nonparticipants to get a separator layer for handling
|
||||
// clips, if there is, on an intermediate surface.
|
||||
// \see ContainerLayer::DefaultComputeEffectiveTransforms().
|
||||
nonparticipants.AppendToTop(item);
|
||||
}
|
||||
WrapSeparatorTransform(aBuilder, this, dirtyRect,
|
||||
&nonparticipants, &participants, index++);
|
||||
resultList.AppendToTop(&participants);
|
||||
}
|
||||
WrapSeparatorTransform(aBuilder, this, dirtyRect,
|
||||
&nonparticipants, &participants, index++);
|
||||
resultList.AppendToTop(&participants);
|
||||
}
|
||||
|
||||
/* We create the opacity outside any transform separators we created,
|
||||
* so that the opacity will be applied to them as groups. When we have
|
||||
* opacity and preserve-3d we break the 'group' nature of opacity in order
|
||||
* to maintain preserve-3d. This matches the behaviour of blink and WebKit,
|
||||
* see bug 1250718.
|
||||
*/
|
||||
if (useOpacity && !resultList.IsEmpty()) {
|
||||
CreateOpacityItem(aBuilder, this, resultList,
|
||||
opacityItemForEventsOnly, containerItemScrollClip, hasPreserve3DChildren);
|
||||
}
|
||||
|
||||
if (isTransformed && !resultList.IsEmpty()) {
|
||||
// Restore clip state now so nsDisplayTransform is clipped properly.
|
||||
if (!HasPerspective() && !useFixedPosition && !useStickyPosition) {
|
||||
clipState.ExitStackingContextContents(&containerItemScrollClip);
|
||||
|
@ -2275,14 +2274,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
aBuilder, this,
|
||||
GetContainingBlock()->GetContent()->GetPrimaryFrame(), &resultList));
|
||||
}
|
||||
|
||||
/* If we need an opacity item, but didn't do it earlier, add it now on the
|
||||
* outside of the transform.
|
||||
*/
|
||||
if (useOpacity && !usingSVGEffects) {
|
||||
CreateOpacityItem(aBuilder, this, resultList, opacityItemForEventsOnly,
|
||||
containerItemScrollClip);
|
||||
}
|
||||
}
|
||||
|
||||
if (useFixedPosition || useStickyPosition) {
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<style>
|
||||
.first {
|
||||
transform: translateZ(10px);
|
||||
background-color: red;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.second {
|
||||
transform: translateZ(5px);
|
||||
background-color: yellow;
|
||||
top: 28px;
|
||||
}
|
||||
.third {
|
||||
background-color: green;
|
||||
top: 48px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.fourth {
|
||||
background-color: blue;
|
||||
top: 68px;
|
||||
}
|
||||
.leaf {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position:absolute;
|
||||
}
|
||||
</style>
|
||||
</head><body>
|
||||
|
||||
<div class="leaf first"></div>
|
||||
<div class="leaf second"></div>
|
||||
<div class="leaf third"></div>
|
||||
<div class="leaf fourth"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<style>
|
||||
.first {
|
||||
transform: translateZ(10px);
|
||||
background-color: blue;
|
||||
top: 60px;
|
||||
}
|
||||
.second {
|
||||
transform: translateZ(5px);
|
||||
background-color: green;
|
||||
top: 40px;
|
||||
}
|
||||
.third {
|
||||
transform: translateZ(-5px);
|
||||
background-color: yellow;
|
||||
top: 20px;
|
||||
}
|
||||
.fourth {
|
||||
transform: translateZ(-10px);
|
||||
background-color: red;
|
||||
}
|
||||
.preserve {
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
.leaf {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position:absolute;
|
||||
}
|
||||
</style>
|
||||
</head><body>
|
||||
|
||||
<div class="preserve">
|
||||
<div class="leaf first"></div>
|
||||
<div class="preserve" style="opacity:0.5">
|
||||
<div class="leaf second"></div>
|
||||
<div class="leaf fourth"></div>
|
||||
</div>
|
||||
<div class="leaf third"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<style>
|
||||
.first {
|
||||
background-color: green;
|
||||
}
|
||||
.second {
|
||||
background-color: blue;
|
||||
top: 58px;
|
||||
}
|
||||
.leaf {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position:absolute;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
</head><body>
|
||||
|
||||
<div class="leaf first"></div>
|
||||
<div class="leaf second"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<style>
|
||||
.first {
|
||||
transform: translateZ(10px);
|
||||
background-color: blue;
|
||||
top: 50px;
|
||||
}
|
||||
.second {
|
||||
transform: translateZ(5px);
|
||||
background-color: green;
|
||||
}
|
||||
.preserve {
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
.leaf {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position:absolute;
|
||||
}
|
||||
</style>
|
||||
</head><body>
|
||||
|
||||
<div class="preserve" style="opacity:0.5">
|
||||
<div class="leaf first"></div>
|
||||
<div class="leaf second"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<style>
|
||||
.first {
|
||||
background-color: green;
|
||||
top: 48px;
|
||||
}
|
||||
.second {
|
||||
top: 88px;
|
||||
}
|
||||
.third {
|
||||
background-color: blue;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.group {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.leaf {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position:absolute;
|
||||
}
|
||||
</style>
|
||||
</head><body>
|
||||
|
||||
<div class="group">
|
||||
<div class="leaf first"></div>
|
||||
<canvas class="leaf second" width="100px" height="100px" id="canvas"></canvas>
|
||||
</div>
|
||||
<div class="leaf third"></div>
|
||||
<script>
|
||||
var canvas = document.getElementById("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.fillStyle = "red";
|
||||
ctx.fillRect(0, 0, 100, 100);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<style>
|
||||
.first {
|
||||
transform: translateZ(10px);
|
||||
background-color: blue;
|
||||
top: 0px;
|
||||
}
|
||||
.second {
|
||||
background-color: green;
|
||||
top: 40px;
|
||||
}
|
||||
.third {
|
||||
top: 80px;
|
||||
}
|
||||
.preserve {
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
.leaf {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position:absolute;
|
||||
}
|
||||
</style>
|
||||
</head><body>
|
||||
|
||||
<div class="preserve">
|
||||
<div class="preserve" style="opacity:0.5">
|
||||
<div class="leaf first"></div>
|
||||
<div class="leaf second"></div>
|
||||
<canvas class="leaf third" width="100px" height="100px" id="canvas"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var canvas = document.getElementById("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.fillStyle = "red";
|
||||
ctx.fillRect(0, 0, 100, 100);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<style>
|
||||
.first {
|
||||
background-color: blue;
|
||||
}
|
||||
.second {
|
||||
background-color: green;
|
||||
top: 48px;
|
||||
}
|
||||
.leaf {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position:absolute;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
</head><body>
|
||||
|
||||
<canvas class="leaf second" width="100px" height="100px" id="canvas"></canvas>
|
||||
<div class="leaf first"></div>
|
||||
<script>
|
||||
var canvas = document.getElementById("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.fillStyle = "red";
|
||||
ctx.fillRect(0, 0, 100, 100);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<style>
|
||||
.first {
|
||||
transform: translateZ(10px);
|
||||
background-color: blue;
|
||||
top: 0px;
|
||||
}
|
||||
.second {
|
||||
background-color: green;
|
||||
top: 40px;
|
||||
}
|
||||
.preserve {
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
.leaf {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position:absolute;
|
||||
}
|
||||
</style>
|
||||
</head><body>
|
||||
|
||||
<div class="preserve">
|
||||
<div class="preserve" style="opacity:0.5">
|
||||
<div class="leaf first"></div>
|
||||
<canvas class="leaf second" width="100px" height="100px" id="canvas"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var canvas = document.getElementById("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.fillStyle = "red";
|
||||
ctx.fillRect(0, 0, 100, 100);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -72,3 +72,7 @@ fuzzy-if(cocoaWidget,128,9) == animate-preserve3d-parent.html animate-preserve3d
|
|||
fuzzy-if(cocoaWidget,128,9) == animate-preserve3d-child.html animate-preserve3d-ref.html # intermittently fuzzy on Mac
|
||||
== animate-backface-hidden.html about:blank
|
||||
== 1245450-1.html green-rect.html
|
||||
fuzzy(1,2000) == opacity-preserve3d-1.html opacity-preserve3d-1-ref.html
|
||||
fuzzy(1,15000) == opacity-preserve3d-2.html opacity-preserve3d-2-ref.html
|
||||
fuzzy(1,10000) == opacity-preserve3d-3.html opacity-preserve3d-3-ref.html
|
||||
fuzzy(1,10000) == opacity-preserve3d-4.html opacity-preserve3d-4-ref.html
|
||||
|
|
Загрузка…
Ссылка в новой задаче