Bug 1389027 - Support nsDisplayPerspective in layers-free mode. r=kats

MozReview-Commit-ID: K0RCuQ8WEE3
This commit is contained in:
Morris Tseng 2017-08-14 17:31:55 +08:00
Родитель 5abb05dc54
Коммит 6391dec171
9 изменённых файлов: 100 добавлений и 9 удалений

Просмотреть файл

@ -278,6 +278,7 @@ AsyncImagePipelineManager::ApplyAsyncImages()
&opacity,
pipeline->mScTransform.IsIdentity() ? nullptr : &pipeline->mScTransform,
wr::TransformStyle::Flat,
nullptr,
pipeline->mMixBlendMode,
nsTArray<wr::WrFilterOp>());

Просмотреть файл

@ -33,6 +33,7 @@ StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParen
mBuilder->PushStackingContext(scBounds, 0, &opacity,
mTransform.IsIdentity() ? nullptr : &mTransform,
wr::TransformStyle::Flat,
nullptr,
wr::ToMixBlendMode(layer->GetMixBlendMode()),
aFilters);
mOrigin = aLayer->Bounds().TopLeft();
@ -57,6 +58,7 @@ StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParen
aOpacityPtr,
aTransformPtr,
wr::TransformStyle::Flat,
nullptr,
wr::ToMixBlendMode(aLayer->GetLayer()->GetMixBlendMode()),
aFilters);
mOrigin = aLayer->Bounds().TopLeft();
@ -71,19 +73,28 @@ StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParen
uint64_t aAnimationsId,
float* aOpacityPtr,
gfx::Matrix4x4* aTransformPtr,
gfx::Matrix4x4* aPerspectivePtr,
const nsTArray<wr::WrFilterOp>& aFilters,
const gfx::CompositionOp& aMixBlendMode)
: mBuilder(&aBuilder)
{
nsRect itemBounds = aDisplayList->GetClippedBoundsWithRespectToASR(aDisplayListBuilder, aItem->GetActiveScrolledRoot());
nsRect childrenVisible = aItem->GetVisibleRectForChildren();
nsRect visibleRect = itemBounds.Intersect(childrenVisible);
nsRect visibleRect;
bool is2d = aTransformPtr && aTransformPtr->Is2D() && !aPerspectivePtr;
if (is2d) {
nsRect itemBounds = aDisplayList->GetClippedBoundsWithRespectToASR(aDisplayListBuilder, aItem->GetActiveScrolledRoot());
nsRect childrenVisible = aItem->GetVisibleRectForChildren();
visibleRect = itemBounds.Intersect(childrenVisible);
} else {
visibleRect = aDisplayList->GetBounds(aDisplayListBuilder);
// The position of bounds are calculated by transform and perspective matrix in 3d case. reset it to (0, 0)
visibleRect.MoveTo(0, 0);
}
float appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
LayerRect bounds = ViewAs<LayerPixel>(LayoutDeviceRect::FromAppUnits(visibleRect, appUnitsPerDevPixel),
PixelCastJustification::WebRenderHasUnitResolution);
// WR will only apply the 'translate' of the transform, so we need to do the scale/rotation manually.
if (aBoundTransform && !aBoundTransform->IsIdentity()) {
if (aBoundTransform && !aBoundTransform->IsIdentity() && is2d) {
bounds.MoveTo(aBoundTransform->TransformPoint(bounds.TopLeft()));
}
@ -96,7 +107,8 @@ StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParen
aAnimationsId,
aOpacityPtr,
aTransformPtr,
wr::TransformStyle::Flat,
is2d ? wr::TransformStyle::Flat : wr::TransformStyle::Preserve3D,
aPerspectivePtr,
wr::ToMixBlendMode(aMixBlendMode),
aFilters);

Просмотреть файл

@ -56,6 +56,7 @@ public:
uint64_t aAnimationsId,
float* aOpacityPtr,
gfx::Matrix4x4* aTransformPtr,
gfx::Matrix4x4* aPerspectivePtr = nullptr,
const nsTArray<wr::WrFilterOp>& aFilters = nsTArray<wr::WrFilterOp>(),
const gfx::CompositionOp& aMixBlendMode = gfx::CompositionOp::OP_OVER);
// This version of the constructor should only be used at the root level

Просмотреть файл

@ -642,6 +642,7 @@ DisplayListBuilder::PushStackingContext(const wr::LayoutRect& aBounds,
const float* aOpacity,
const gfx::Matrix4x4* aTransform,
wr::TransformStyle aTransformStyle,
const gfx::Matrix4x4* aPerspective,
const wr::MixBlendMode& aMixBlendMode,
const nsTArray<wr::WrFilterOp>& aFilters)
{
@ -650,11 +651,16 @@ DisplayListBuilder::PushStackingContext(const wr::LayoutRect& aBounds,
matrix = ToLayoutTransform(*aTransform);
}
const wr::LayoutTransform* maybeTransform = aTransform ? &matrix : nullptr;
wr::LayoutTransform perspective;
if (aPerspective) {
perspective = ToLayoutTransform(*aPerspective);
}
const wr::LayoutTransform* maybePerspective = aPerspective ? &perspective : nullptr;
WRDL_LOG("PushStackingContext b=%s t=%s\n", Stringify(aBounds).c_str(),
aTransform ? Stringify(*aTransform).c_str() : "none");
wr_dp_push_stacking_context(mWrState, aBounds, aAnimationId, aOpacity,
maybeTransform, aTransformStyle, aMixBlendMode,
aFilters.Elements(), aFilters.Length());
maybeTransform, aTransformStyle, maybePerspective,
aMixBlendMode, aFilters.Elements(), aFilters.Length());
}
void

Просмотреть файл

@ -173,6 +173,7 @@ public:
const float* aOpacity,
const gfx::Matrix4x4* aTransform,
wr::TransformStyle aTransformStyle,
const gfx::Matrix4x4* aPerspective,
const wr::MixBlendMode& aMixBlendMode,
const nsTArray<wr::WrFilterOp>& aFilters);
void PopStackingContext();

Просмотреть файл

@ -998,6 +998,7 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState,
opacity: *const f32,
transform: *const LayoutTransform,
transform_style: TransformStyle,
perspective: *const LayoutTransform,
mix_blend_mode: MixBlendMode,
filters: *const WrFilterOp,
filter_count: usize) {
@ -1038,13 +1039,18 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState,
_ => Some(PropertyBinding::Binding(PropertyBindingKey::new(animation_id))),
};
let perspective_ref = unsafe { perspective.as_ref() };
let perspective = match perspective_ref {
Some(perspective) => Some(perspective.clone()),
None => None,
};
state.frame_builder
.dl_builder
.push_stacking_context(webrender_api::ScrollPolicy::Scrollable,
bounds,
transform_binding,
transform_style,
None,
perspective,
mix_blend_mode,
filters);
}

Просмотреть файл

@ -943,6 +943,7 @@ void wr_dp_push_stacking_context(WrState *aState,
const float *aOpacity,
const LayoutTransform *aTransform,
TransformStyle aTransformStyle,
const LayoutTransform *aPerspective,
MixBlendMode aMixBlendMode,
const WrFilterOp *aFilters,
size_t aFilterCount)

Просмотреть файл

@ -6157,6 +6157,7 @@ nsDisplayOpacity::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuil
animationsId,
opacityForSC,
nullptr,
nullptr,
filters);
aManager->CreateWebRenderCommandsFromDisplayList(&mList,
@ -6208,7 +6209,7 @@ nsDisplayBlendMode::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBu
{
nsTArray<mozilla::wr::WrFilterOp> filters;
StackingContextHelper sc(aSc, aBuilder, aDisplayListBuilder, this,
&mList, nullptr, 0, nullptr, nullptr,
&mList, nullptr, 0, nullptr, nullptr, nullptr,
filters, nsCSSRendering::GetGFXBlendMode(mBlendMode));
return nsDisplayWrapList::CreateWebRenderCommands(aBuilder, sc, aParentCommands,
@ -7853,6 +7854,7 @@ nsDisplayTransform::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBu
animationsId,
nullptr,
transformForSC,
nullptr,
filters);
return mStoredList.CreateWebRenderCommands(aBuilder, sc, aParentCommands,
@ -8435,6 +8437,61 @@ nsDisplayPerspective::GetLayerState(nsDisplayListBuilder* aBuilder,
return LAYER_ACTIVE_FORCE;
}
bool
nsDisplayPerspective::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc,
nsTArray<WebRenderParentCommand>& aParentCommands,
WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
float appUnitsPerPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
Matrix4x4 perspectiveMatrix;
DebugOnly<bool> hasPerspective =
nsDisplayTransform::ComputePerspectiveMatrix(mTransformFrame, appUnitsPerPixel,
perspectiveMatrix);
MOZ_ASSERT(hasPerspective, "Why did we create nsDisplayPerspective?");
/*
* ClipListToRange can remove our child after we were created.
*/
if (!mList.GetChildren()->GetTop()) {
return false;
}
/*
* The resulting matrix is still in the coordinate space of the transformed
* frame. Append a translation to the reference frame coordinates.
*/
nsDisplayTransform* transform =
static_cast<nsDisplayTransform*>(mList.GetChildren()->GetTop());
Point3D newOrigin =
Point3D(NSAppUnitsToFloatPixels(transform->ToReferenceFrame().x, appUnitsPerPixel),
NSAppUnitsToFloatPixels(transform->ToReferenceFrame().y, appUnitsPerPixel),
0.0f);
Point3D roundedOrigin(NS_round(newOrigin.x),
NS_round(newOrigin.y),
0);
gfx::Matrix4x4 transformForSC = gfx::Matrix4x4::Translation(roundedOrigin);
nsTArray<mozilla::wr::WrFilterOp> filters;
StackingContextHelper sc(aSc,
aBuilder,
aDisplayListBuilder,
this,
mList.GetChildren(),
nullptr,
0,
nullptr,
&transformForSC,
&perspectiveMatrix,
filters);
return mList.CreateWebRenderCommands(aBuilder, sc, aParentCommands,
aManager, aDisplayListBuilder);
}
int32_t
nsDisplayPerspective::ZIndex() const
{
@ -9199,6 +9256,7 @@ nsDisplayFilter::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuild
0,
nullptr,
nullptr,
nullptr,
wrFilters);
nsDisplaySVGEffects::CreateWebRenderCommands(aBuilder, sc, aParentCommands, aManager, aDisplayListBuilder);

Просмотреть файл

@ -5094,6 +5094,11 @@ public:
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc,
nsTArray<WebRenderParentCommand>& aParentCommands,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) override;
virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) override
{