Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/layers/AsyncCompositionManager.h
Line
Count
Source (jump to first uncovered line)
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/. */
6
7
#ifndef GFX_ASYNCCOMPOSITIONMANAGER_H
8
#define GFX_ASYNCCOMPOSITIONMANAGER_H
9
10
#include "Units.h"                      // for ScreenPoint, etc
11
#include "mozilla/layers/LayerManagerComposite.h"  // for LayerManagerComposite
12
#include "mozilla/Attributes.h"         // for final, etc
13
#include "mozilla/RefPtr.h"             // for RefCounted
14
#include "mozilla/TimeStamp.h"          // for TimeStamp
15
#include "mozilla/gfx/BasePoint.h"      // for BasePoint
16
#include "mozilla/gfx/Matrix.h"         // for Matrix4x4
17
#include "mozilla/HalScreenConfiguration.h" // For ScreenOrientation
18
#include "mozilla/layers/FrameUniformityData.h" // For FrameUniformityData
19
#include "mozilla/layers/LayersMessages.h"  // for TargetConfig
20
#include "mozilla/RefPtr.h"                   // for nsRefPtr
21
#include "nsISupportsImpl.h"            // for LayerManager::AddRef, etc
22
#include "CompositorBridgeParent.h"     // for TransformsToSkip
23
24
namespace mozilla {
25
namespace layers {
26
27
class Layer;
28
class LayerManagerComposite;
29
class AutoResolveRefLayers;
30
class CompositorBridgeParent;
31
32
// Represents async transforms consisting of a scale and a translation.
33
struct AsyncTransform {
34
  explicit AsyncTransform(LayerToParentLayerScale aScale = LayerToParentLayerScale(),
35
                          ParentLayerPoint aTranslation = ParentLayerPoint())
36
    : mScale(aScale)
37
    , mTranslation(aTranslation)
38
0
  {}
39
40
  operator AsyncTransformComponentMatrix() const
41
0
  {
42
0
    return AsyncTransformComponentMatrix::Scaling(mScale.scale, mScale.scale, 1)
43
0
        .PostTranslate(mTranslation.x, mTranslation.y, 0);
44
0
  }
45
46
0
  bool operator==(const AsyncTransform& rhs) const {
47
0
    return mTranslation == rhs.mTranslation && mScale == rhs.mScale;
48
0
  }
49
50
0
  bool operator!=(const AsyncTransform& rhs) const {
51
0
    return !(*this == rhs);
52
0
  }
53
54
  LayerToParentLayerScale mScale;
55
  ParentLayerPoint mTranslation;
56
};
57
58
/**
59
 * Manage async composition effects. This class is only used with OMTC and only
60
 * lives on the compositor thread. It is a layer on top of the layer manager
61
 * (LayerManagerComposite) which deals with elements of composition which are
62
 * usually dealt with by dom or layout when main thread rendering, but which can
63
 * short circuit that stuff to directly affect layers as they are composited,
64
 * for example, off-main thread animation, async video, async pan/zoom.
65
 */
66
class AsyncCompositionManager final
67
{
68
  friend class AutoResolveRefLayers;
69
  ~AsyncCompositionManager();
70
71
public:
72
  NS_INLINE_DECL_REFCOUNTING(AsyncCompositionManager)
73
74
  explicit AsyncCompositionManager(CompositorBridgeParent* aParent, HostLayerManager* aManager);
75
76
  /**
77
   * This forces the is-first-paint flag to true. This is intended to
78
   * be called by the widget code when it loses its viewport information
79
   * (or for whatever reason wants to refresh the viewport information).
80
   * The information refresh happens because the compositor will call
81
   * AndroidDynamicToolbarAnimator::FirstPaint() on the next frame of composition.
82
   */
83
0
  void ForceIsFirstPaint() { mIsFirstPaint = true; }
84
85
  // Sample transforms for layer trees.  Return true to request
86
  // another animation frame.
87
  bool TransformShadowTree(
88
    TimeStamp aCurrentFrame,
89
    TimeDuration aVsyncRate,
90
    CompositorBridgeParentBase::TransformsToSkip aSkip =
91
      CompositorBridgeParentBase::TransformsToSkip::NoneOfThem);
92
93
  // Calculates the correct rotation and applies the transform to
94
  // our layer manager
95
  void ComputeRotation();
96
97
  // Call after updating our layer tree.
98
  void Updated(bool isFirstPaint, const TargetConfig& aTargetConfig)
99
0
  {
100
0
    mIsFirstPaint |= isFirstPaint;
101
0
    mLayersUpdated = true;
102
0
    mTargetConfig = aTargetConfig;
103
0
  }
104
105
  bool RequiresReorientation(hal::ScreenOrientation aOrientation) const
106
0
  {
107
0
    return mTargetConfig.orientation() != aOrientation;
108
0
  }
109
110
  // True if the underlying layer tree is ready to be composited.
111
0
  bool ReadyForCompose() { return mReadyForCompose; }
112
113
  // Returns true if the next composition will be the first for a
114
  // particular document.
115
0
  bool IsFirstPaint() { return mIsFirstPaint; }
116
117
  // GetFrameUniformity will return the frame uniformity for each layer attached to an APZ
118
  // from the recorded data in RecordShadowTransform
119
  void GetFrameUniformity(FrameUniformityData* aFrameUniformityData);
120
121
  // Stores the clip rect of a layer in two parts: a fixed part and a scrolled
122
  // part. When a layer is fixed, the clip needs to be adjusted to account for
123
  // async transforms. Only the fixed part needs to be adjusted, so we need
124
  // to store the two parts separately.
125
  struct ClipParts {
126
    Maybe<ParentLayerIntRect> mFixedClip;
127
    Maybe<ParentLayerIntRect> mScrolledClip;
128
129
0
    Maybe<ParentLayerIntRect> Intersect() const {
130
0
      return IntersectMaybeRects(mFixedClip, mScrolledClip);
131
0
    }
132
  };
133
134
  typedef std::map<Layer*, ClipParts> ClipPartsCache;
135
136
private:
137
  // Return true if an AsyncPanZoomController content transform was
138
  // applied for |aLayer|. |*aOutFoundRoot| is set to true on Android only, if
139
  // one of the metrics on one of the layers was determined to be the "root"
140
  // and its state was synced to the Java front-end. |aOutFoundRoot| must be
141
  // non-null.
142
  bool ApplyAsyncContentTransformToTree(Layer* aLayer,
143
                                        bool* aOutFoundRoot);
144
  /**
145
   * Update the shadow transform for aLayer assuming that is a scrollbar,
146
   * so that it stays in sync with the content that is being scrolled by APZ.
147
   */
148
  void ApplyAsyncTransformToScrollbar(Layer* aLayer);
149
150
  /**
151
   * Adds a translation to the transform of any fixed position (whose parent
152
   * layer is not fixed) or sticky position layer descendant of
153
   * |aTransformedSubtreeRoot|. The translation is chosen so that the layer's
154
   * anchor point relative to |aTransformedSubtreeRoot|'s parent layer is the same
155
   * as it was when |aTransformedSubtreeRoot|'s GetLocalTransform() was
156
   * |aPreviousTransformForRoot|. |aCurrentTransformForRoot| is
157
   * |aTransformedSubtreeRoot|'s current GetLocalTransform() modulo any
158
   * overscroll-related transform, which we don't want to adjust for.
159
   * For sticky position layers, the translation is further intersected with
160
   * the layer's sticky scroll ranges.
161
   * This function will also adjust layers so that the given content document
162
   * fixed position margins will be respected during asynchronous panning and
163
   * zooming.
164
   * |aTransformScrollId| is the scroll id of the scroll frame that scrolls
165
   * |aTransformedSubtreeRoot|.
166
   * |aClipPartsCache| optionally maps layers to separate fixed and scrolled
167
   * clips, so we can only adjust the fixed portion.
168
   * This function has a recursive implementation; aStartTraversalAt specifies
169
   * where to start the current recursion of the traversal. For the initial
170
   * call, it should be the same as aTrasnformedSubtreeRoot.
171
   */
172
  void AlignFixedAndStickyLayers(Layer* aTransformedSubtreeRoot,
173
                                 Layer* aStartTraversalAt,
174
                                 FrameMetrics::ViewID aTransformScrollId,
175
                                 const LayerToParentLayerMatrix4x4& aPreviousTransformForRoot,
176
                                 const LayerToParentLayerMatrix4x4& aCurrentTransformForRoot,
177
                                 const ScreenMargin& aFixedLayerMargins,
178
                                 ClipPartsCache* aClipPartsCache);
179
180
  /**
181
   * DRAWING PHASE ONLY
182
   *
183
   * For reach RefLayer in our layer tree, look up its referent and connect it
184
   * to the layer tree, if found.
185
   * aHasRemoteContent - indicates if the layer tree contains a remote reflayer.
186
   *  May be null.
187
   * aResolvePlugins - incoming value indicates if plugin windows should be
188
   *  updated through a call on aCompositor's UpdatePluginWindowState. Applies
189
   *  to linux and windows only, may be null. On return value indicates
190
   *  if any updates occured.
191
   */
192
  void ResolveRefLayers(CompositorBridgeParent* aCompositor, bool* aHasRemoteContent,
193
                        bool* aResolvePlugins);
194
195
  /**
196
   * Detaches all referents resolved by ResolveRefLayers.
197
   * Assumes that mLayerManager->GetRoot() and mTargetConfig have not changed
198
   * since ResolveRefLayers was called.
199
   */
200
  void DetachRefLayers();
201
202
  // Records the shadow transforms for the tree of layers rooted at the given layer
203
  void RecordShadowTransforms(Layer* aLayer);
204
205
  TargetConfig mTargetConfig;
206
  CSSRect mContentRect;
207
208
  RefPtr<HostLayerManager> mLayerManager;
209
  // When this flag is set, the next composition will be the first for a
210
  // particular document (i.e. the document displayed on the screen will change).
211
  // This happens when loading a new page or switching tabs. We notify the
212
  // front-end (e.g. Java on Android) about this so that it take the new page
213
  // size and zoom into account when providing us with the next view transform.
214
  bool mIsFirstPaint;
215
216
  // This flag is set during a layers update, so that the first composition
217
  // after a layers update has it set. It is cleared after that first composition.
218
  bool mLayersUpdated;
219
220
  bool mReadyForCompose;
221
222
  gfx::Matrix mWorldTransform;
223
  LayerTransformRecorder mLayerTransformRecorder;
224
225
  TimeStamp mPreviousFrameTimeStamp;
226
227
  MOZ_NON_OWNING_REF CompositorBridgeParent* mCompositorBridge;
228
229
#ifdef MOZ_WIDGET_ANDROID
230
public:
231
  void SetFixedLayerMargins(ScreenIntCoord aTop, ScreenIntCoord aBottom);
232
private:
233
  // The following two fields are only needed on Fennec with C++ APZ, because
234
  // then we need to reposition the gecko scrollbar to deal with the
235
  // dynamic toolbar shifting content around.
236
  FrameMetrics::ViewID mRootScrollableId;
237
  ScreenMargin mFixedLayerMargins;
238
#endif
239
};
240
241
class MOZ_STACK_CLASS AutoResolveRefLayers {
242
public:
243
  explicit AutoResolveRefLayers(AsyncCompositionManager* aManager,
244
                                CompositorBridgeParent* aCompositor = nullptr,
245
                                bool* aHasRemoteContent = nullptr,
246
                                bool* aResolvePlugins = nullptr) :
247
    mManager(aManager)
248
0
  {
249
0
    if (mManager) {
250
0
      mManager->ResolveRefLayers(aCompositor, aHasRemoteContent, aResolvePlugins);
251
0
    }
252
0
  }
253
254
  ~AutoResolveRefLayers()
255
0
  {
256
0
    if (mManager) {
257
0
      mManager->DetachRefLayers();
258
0
    }
259
0
  }
260
261
private:
262
  AsyncCompositionManager* mManager;
263
264
  AutoResolveRefLayers(const AutoResolveRefLayers&) = delete;
265
  AutoResolveRefLayers& operator=(const AutoResolveRefLayers&) = delete;
266
};
267
268
} // namespace layers
269
} // namespace mozilla
270
271
#endif