Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "WebRenderContainerLayer.h"
7 :
8 : #include <inttypes.h>
9 : #include "gfxPrefs.h"
10 : #include "LayersLogging.h"
11 : #include "mozilla/layers/ScrollingLayersHelper.h"
12 : #include "mozilla/layers/StackingContextHelper.h"
13 : #include "mozilla/layers/WebRenderBridgeChild.h"
14 : #include "mozilla/webrender/WebRenderTypes.h"
15 : #include "UnitTransforms.h"
16 :
17 : namespace mozilla {
18 : namespace layers {
19 :
20 : void
21 0 : WebRenderContainerLayer::ClearAnimations()
22 : {
23 :
24 0 : if (!GetAnimations().IsEmpty()) {
25 0 : mManager->AsWebRenderLayerManager()->
26 0 : AddCompositorAnimationsIdForDiscard(GetCompositorAnimationsId());
27 : }
28 :
29 0 : Layer::ClearAnimations();
30 0 : }
31 :
32 : void
33 0 : WebRenderContainerLayer::UpdateTransformDataForAnimation()
34 : {
35 0 : for (Animation& animation : mAnimations) {
36 0 : if (animation.property() == eCSSProperty_transform) {
37 0 : TransformData& transformData = animation.data().get_TransformData();
38 0 : transformData.inheritedXScale() = GetInheritedXScale();
39 0 : transformData.inheritedYScale() = GetInheritedYScale();
40 0 : transformData.hasPerspectiveParent() =
41 0 : GetParent() && GetParent()->GetTransformIsPerspective();
42 : }
43 : }
44 0 : }
45 :
46 : void
47 0 : WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
48 : const StackingContextHelper& aSc)
49 : {
50 0 : nsTArray<LayerPolygon> children = SortChildrenBy3DZOrder(SortMode::WITHOUT_GEOMETRY);
51 :
52 0 : gfx::Matrix4x4 transform = GetTransform();
53 0 : gfx::Matrix4x4* transformForSC = &transform;
54 0 : float opacity = GetLocalOpacity();
55 0 : float* opacityForSC = &opacity;
56 0 : uint64_t animationsId = 0;
57 :
58 0 : if (gfxPrefs::WebRenderOMTAEnabled() &&
59 0 : !GetAnimations().IsEmpty()) {
60 0 : MOZ_ASSERT(GetCompositorAnimationsId());
61 :
62 0 : OptionalOpacity opacityForCompositor = void_t();
63 0 : OptionalTransform transformForCompositor = void_t();
64 :
65 : // Update opacity as nullptr in stacking context if there exists
66 : // opacity animation, the opacity value will be resolved
67 : // after animation sampling on the compositor
68 0 : if (HasOpacityAnimation()) {
69 0 : opacityForSC = nullptr;
70 : // Pass default opacity to compositor in case gecko fails to
71 : // get animated value after animation sampling.
72 0 : opacityForCompositor = opacity;
73 : }
74 :
75 : // Update transfrom as nullptr in stacking context if there exists
76 : // transform animation, the transform value will be resolved
77 : // after animation sampling on the compositor
78 0 : if (HasTransformAnimation()) {
79 0 : transformForSC = nullptr;
80 : // Pass default transform to compositor in case gecko fails to
81 : // get animated value after animation sampling.
82 0 : transformForCompositor = transform;
83 0 : UpdateTransformDataForAnimation();
84 : }
85 :
86 0 : animationsId = GetCompositorAnimationsId();
87 : OpAddCompositorAnimations
88 0 : anim(CompositorAnimations(GetAnimations(), animationsId),
89 0 : transformForCompositor, opacityForCompositor);
90 0 : WrBridge()->AddWebRenderParentCommand(anim);
91 : }
92 :
93 : // If APZ is enabled and this layer is a scroll thumb, then it might need
94 : // to move in the compositor to represent the async scroll position. So we
95 : // ensure that there is an animations id set on it, we will use this to give
96 : // WebRender updated transforms for composition.
97 0 : if (WrManager()->AsyncPanZoomEnabled() &&
98 0 : GetScrollThumbData().mDirection != ScrollDirection::NONE) {
99 : // A scroll thumb better not have a transform animation already or we're
100 : // going to end up clobbering it with APZ animating it too.
101 0 : MOZ_ASSERT(transformForSC);
102 :
103 0 : EnsureAnimationsId();
104 0 : animationsId = GetCompositorAnimationsId();
105 : // We need to set the transform in the stacking context to null for it to
106 : // pick up and install the animation id.
107 0 : transformForSC = nullptr;
108 : }
109 :
110 0 : if (transformForSC && transform.IsIdentity()) {
111 : // If the transform is an identity transform, strip it out so that WR
112 : // doesn't turn this stacking context into a reference frame, as it
113 : // affects positioning. Bug 1345577 tracks a better fix.
114 0 : transformForSC = nullptr;
115 : }
116 :
117 0 : nsTArray<WrFilterOp> filters;
118 0 : for (const CSSFilter& filter : this->GetFilterChain()) {
119 0 : filters.AppendElement(wr::ToWrFilterOp(filter));
120 : }
121 :
122 0 : ScrollingLayersHelper scroller(this, aBuilder, aSc);
123 0 : StackingContextHelper sc(aSc, aBuilder, this, animationsId, opacityForSC, transformForSC, filters);
124 :
125 0 : LayerRect rect = Bounds();
126 0 : DumpLayerInfo("ContainerLayer", rect);
127 :
128 0 : for (LayerPolygon& child : children) {
129 0 : if (child.layer->IsBackfaceHidden()) {
130 0 : continue;
131 : }
132 0 : ToWebRenderLayer(child.layer)->RenderLayer(aBuilder, sc);
133 : }
134 0 : }
135 :
136 : void
137 0 : WebRenderRefLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
138 : const StackingContextHelper& aSc)
139 : {
140 0 : ScrollingLayersHelper scroller(this, aBuilder, aSc);
141 :
142 0 : ParentLayerRect bounds = GetLocalTransformTyped().TransformBounds(Bounds());
143 : // As with WebRenderTextLayer, because we don't push a stacking context for
144 : // this layer, WR doesn't know about the transform on this layer. Therefore
145 : // we need to apply that transform to the bounds before we pass it on to WR.
146 : // The conversion from ParentLayerPixel to LayerPixel below is a result of
147 : // changing the reference layer from "this layer" to the "the layer that
148 : // created aSc".
149 : LayerRect rect = ViewAs<LayerPixel>(bounds,
150 0 : PixelCastJustification::MovingDownToChildren);
151 0 : DumpLayerInfo("RefLayer", rect);
152 :
153 0 : WrRect r = aSc.ToRelativeWrRect(rect);
154 0 : aBuilder.PushIFrame(r, wr::AsPipelineId(mId));
155 0 : }
156 :
157 : } // namespace layers
158 : } // namespace mozilla
|