gecko-dev/gfx/layers/wr/WebRenderContainerLayer.cpp

147 строки
5.5 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebRenderContainerLayer.h"
#include <inttypes.h>
#include "gfxPrefs.h"
#include "LayersLogging.h"
#include "mozilla/layers/ScrollingLayersHelper.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "UnitTransforms.h"
namespace mozilla {
namespace layers {
void
WebRenderContainerLayer::UpdateTransformDataForAnimation()
{
for (Animation& animation : mAnimationInfo.GetAnimations()) {
if (animation.property() == eCSSProperty_transform) {
TransformData& transformData = animation.data().get_TransformData();
transformData.inheritedXScale() = GetInheritedXScale();
transformData.inheritedYScale() = GetInheritedYScale();
transformData.hasPerspectiveParent() =
GetParent() && GetParent()->GetTransformIsPerspective();
}
}
}
void
WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc)
{
nsTArray<LayerPolygon> children = SortChildrenBy3DZOrder(SortMode::WITHOUT_GEOMETRY);
gfx::Matrix4x4 transform = GetTransform();
gfx::Matrix4x4* transformForSC = &transform;
float opacity = GetLocalOpacity();
float* opacityForSC = &opacity;
uint64_t animationsId = 0;
if (gfxPrefs::WebRenderOMTAEnabled() &&
!GetAnimations().IsEmpty()) {
MOZ_ASSERT(GetCompositorAnimationsId());
OptionalOpacity opacityForCompositor = void_t();
OptionalTransform transformForCompositor = void_t();
// Update opacity as nullptr in stacking context if there exists
// opacity animation, the opacity value will be resolved
// after animation sampling on the compositor
if (HasOpacityAnimation()) {
opacityForSC = nullptr;
// Pass default opacity to compositor in case gecko fails to
// get animated value after animation sampling.
opacityForCompositor = opacity;
}
// Update transfrom as nullptr in stacking context if there exists
// transform animation, the transform value will be resolved
// after animation sampling on the compositor
if (HasTransformAnimation()) {
transformForSC = nullptr;
// Pass default transform to compositor in case gecko fails to
// get animated value after animation sampling.
transformForCompositor = transform;
UpdateTransformDataForAnimation();
}
animationsId = GetCompositorAnimationsId();
OpAddCompositorAnimations
anim(CompositorAnimations(GetAnimations(), animationsId),
transformForCompositor, opacityForCompositor);
WrBridge()->AddWebRenderParentCommand(anim);
}
// If APZ is enabled and this layer is a scroll thumb, then it might need
// to move in the compositor to represent the async scroll position. So we
// ensure that there is an animations id set on it, we will use this to give
// WebRender updated transforms for composition.
if (WrManager()->AsyncPanZoomEnabled() &&
GetScrollThumbData().mDirection != ScrollDirection::NONE) {
// A scroll thumb better not have a transform animation already or we're
// going to end up clobbering it with APZ animating it too.
MOZ_ASSERT(transformForSC);
mAnimationInfo.EnsureAnimationsId();
animationsId = GetCompositorAnimationsId();
// We need to set the transform in the stacking context to null for it to
// pick up and install the animation id.
transformForSC = nullptr;
}
if (transformForSC && transform.IsIdentity()) {
// If the transform is an identity transform, strip it out so that WR
// doesn't turn this stacking context into a reference frame, as it
// affects positioning. Bug 1345577 tracks a better fix.
transformForSC = nullptr;
}
nsTArray<wr::WrFilterOp> filters;
for (const CSSFilter& filter : this->GetFilterChain()) {
filters.AppendElement(wr::ToWrFilterOp(filter));
}
ScrollingLayersHelper scroller(this, aBuilder, aSc);
StackingContextHelper sc(aSc, aBuilder, this, animationsId, opacityForSC, transformForSC, filters);
LayerRect rect = Bounds();
DumpLayerInfo("ContainerLayer", rect);
for (LayerPolygon& child : children) {
if (child.layer->IsBackfaceHidden()) {
continue;
}
ToWebRenderLayer(child.layer)->RenderLayer(aBuilder, sc);
}
}
void
WebRenderRefLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc)
{
ScrollingLayersHelper scroller(this, aBuilder, aSc);
ParentLayerRect bounds = GetLocalTransformTyped().TransformBounds(Bounds());
// As with WebRenderTextLayer, because we don't push a stacking context for
// this layer, WR doesn't know about the transform on this layer. Therefore
// we need to apply that transform to the bounds before we pass it on to WR.
// The conversion from ParentLayerPixel to LayerPixel below is a result of
// changing the reference layer from "this layer" to the "the layer that
// created aSc".
LayerRect rect = ViewAs<LayerPixel>(bounds,
PixelCastJustification::MovingDownToChildren);
DumpLayerInfo("RefLayer", rect);
wr::LayoutRect r = aSc.ToRelativeLayoutRect(rect);
aBuilder.PushIFrame(r, wr::AsPipelineId(mId));
}
} // namespace layers
} // namespace mozilla