Bug 1913773 - Ensure mCurrentShmem is valid. r=aosmond
[gecko.git] / gfx / layers / AnimationHelper.h
blobb3484c2cba958f955a120cbdc65d1deeb1bd8b0d
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_layers_AnimationHelper_h
8 #define mozilla_layers_AnimationHelper_h
10 #include "mozilla/dom/Nullable.h"
11 #include "mozilla/layers/AnimationStorageData.h"
12 #include "mozilla/layers/LayersMessages.h" // for TransformData, etc
13 #include "mozilla/webrender/WebRenderTypes.h" // for RenderRoot
14 #include "mozilla/TimeStamp.h" // for TimeStamp
15 #include "mozilla/TimingParams.h"
16 #include "mozilla/Types.h" // for SideBits
17 #include "X11UndefineNone.h"
18 #include <unordered_map>
20 namespace mozilla::layers {
21 class Animation;
22 class APZSampler;
23 class CompositorAnimationStorage;
24 struct AnimatedValue;
26 using AnimationArray = nsTArray<layers::Animation>;
27 using SampledAnimationArray = AutoTArray<RefPtr<StyleAnimationValue>, 1>;
29 /**
30 * This utility class allows reusing code between the webrender and
31 * non-webrender compositor-side implementations. It provides
32 * utility functions for sampling animations at particular timestamps.
34 class AnimationHelper {
35 public:
36 struct SampleResult {
37 enum class Type : uint8_t { None, Skipped, Sampled };
38 enum class Reason : uint8_t { None, ScrollToDelayPhase };
39 Type mType = Type::None;
40 Reason mReason = Reason::None;
42 SampleResult() = default;
43 SampleResult(Type aType, Reason aReason) : mType(aType), mReason(aReason) {}
45 static SampleResult Skipped() { return {Type::Skipped, Reason::None}; }
46 static SampleResult Sampled() { return {Type::Sampled, Reason::None}; }
48 bool IsNone() { return mType == Type::None; }
49 bool IsSkipped() { return mType == Type::Skipped; }
50 bool IsSampled() { return mType == Type::Sampled; }
53 /**
54 * Sample animations based on a given time stamp for a element(layer) with
55 * its animation data.
56 * Generally |aPreviousFrameTime| is used for the sampling if it's
57 * supplied to make the animation more in sync with other animations on the
58 * main-thread. But in the case where the animation just started at the time
59 * when the animation was sent to the compositor, |aCurrentFrameTime| is used
60 * for sampling instead to avoid flicker.
62 * Returns SampleResult::None if none of the animations are producing a result
63 * (e.g. they are in the delay phase with no backwards fill),
64 * SampleResult::Skipped if the animation output did not change since the last
65 * call of this function,
66 * SampleResult::Sampled if the animation output was updated.
68 * The only exception is the scroll-driven animation. When the user move the
69 * scrollbar to make the animations go from active phase to delay phase, this
70 * returns SampleResult::None but sets its |mReason| to
71 * Reason::ScrollToDelayPhase. The caller can check this flag so we can store
72 * the base style into the hash table to make sure we have the correct
73 * rendering result. The base style stays in the hash table until we sync with
74 * main thread.
76 * Using the same example from ExtractAnimations (below):
78 * Input |aPropertyAnimationGroups| (ignoring the base animation style):
80 * [
81 * Group A: [ { rotate, Animation A }, { rotate, Animation B } ],
82 * Group B: [ { scale, Animation B } ],
83 * Group C: [ { transform, Animation A }, { transform, Animation B } ],
84 * ]
86 * For each property group, this function interpolates each animation in turn,
87 * using the result of interpolating one animation as input for the next such
88 * that it reduces each property group to a single output value:
90 * [
91 * { rotate, StyleAnimationValue },
92 * { scale, StyleAnimationValue },
93 * { transform, StyleAnimationValue },
94 * ]
96 * For transform animations, the caller (SampleAnimations) will combine the
97 * result of the various transform properties into a final matrix.
99 static SampleResult SampleAnimationForEachNode(
100 const APZSampler* aAPZSampler, const LayersId& aLayersId,
101 const MutexAutoLock& aProofOfMapLock, TimeStamp aPreviousFrameTime,
102 TimeStamp aCurrentFrameTime, const AnimatedValue* aPreviousValue,
103 nsTArray<PropertyAnimationGroup>& aPropertyAnimationGroups,
104 SampledAnimationArray& aAnimationValues /* output */);
107 * Extract organized animation data by property into an array of
108 * PropertyAnimationGroup objects.
110 * For example, suppose we have the following animations:
112 * Animation A: [ transform, rotate ]
113 * Animation B: [ rotate, scale ]
114 * Animation C: [ transform ]
115 * Animation D: [ opacity ]
117 * When we go to send transform-like properties to the compositor, we
118 * sort them as follows:
121 * { rotate: Animation A (rotate segments only) },
122 * { rotate: Animation B ( " " ) },
123 * { scale: Animation B (scale segments only) },
124 * { transform: Animation A (transform segments only) },
125 * { transform: Animation C ( " " ) },
128 * In this function, we group these animations together by property producing
129 * output such as the following:
132 * [ { rotate, Animation A }, { rotate, Animation B } ],
133 * [ { scale, Animation B } ],
134 * [ { transform, Animation A }, { transform, Animation B } ],
137 * In the process of grouping these animations, we also convert their values
138 * from the rather compact representation we use for transferring across the
139 * IPC boundary into something we can readily use for sampling.
141 * Note: the animation groups:
142 * 1. transform-like properties: transfrom, translate, rotate, scale,
143 * offset-*.
144 * 2. opacity property: opacity.
145 * 3. background color property: background-color.
147 static AnimationStorageData ExtractAnimations(
148 const LayersId& aLayersId, const AnimationArray& aAnimations,
149 const CompositorAnimationStorage* aStorage,
150 const TimeStamp& aPreviousSampleTime);
153 * Get a unique id to represent the compositor animation between child
154 * and parent side. This id will be used as a key to store animation
155 * data in the CompositorAnimationStorage per compositor.
156 * Each layer on the content side calls this when it gets new animation
157 * data.
159 static uint64_t GetNextCompositorAnimationsId();
162 * Convert an array of animation values into a matrix given the corresponding
163 * transform parameters. |aValue| must be a transform-like value
164 * (e.g. transform, translate etc.).
166 static gfx::Matrix4x4 ServoAnimationValueToMatrix4x4(
167 const SampledAnimationArray& aValue, const TransformData& aTransformData,
168 gfx::Path* aCachedMotionPath);
171 * Returns true if |aPrerenderedRect| transformed by |aTransform| were
172 * composited in |aClipRect| there appears area which wasn't pre-rendered
173 * on the main-thread. I.e. checkerboarding.
175 static bool ShouldBeJank(const LayoutDeviceRect& aPrerenderedRect,
176 SideBits aOverflowedSides,
177 const gfx::Matrix4x4& aTransform,
178 const ParentLayerRect& aClipRect);
181 } // namespace mozilla::layers
183 #endif // mozilla_layers_AnimationHelper_h