|
1 /* -*- Mode: C++; tab-width: 20; 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 #ifndef GFX_ASYNCCOMPOSITIONMANAGER_H |
|
7 #define GFX_ASYNCCOMPOSITIONMANAGER_H |
|
8 |
|
9 #include "Units.h" // for LayerPoint, etc |
|
10 #include "mozilla/layers/LayerManagerComposite.h" // for LayerManagerComposite |
|
11 #include "gfx3DMatrix.h" // for gfx3DMatrix |
|
12 #include "mozilla/Attributes.h" // for MOZ_DELETE, MOZ_FINAL, etc |
|
13 #include "mozilla/RefPtr.h" // for RefCounted |
|
14 #include "mozilla/TimeStamp.h" // for TimeStamp |
|
15 #include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation |
|
16 #include "mozilla/gfx/BasePoint.h" // for BasePoint |
|
17 #include "mozilla/layers/LayersMessages.h" // for TargetConfig |
|
18 #include "nsAutoPtr.h" // for nsRefPtr |
|
19 #include "nsISupportsImpl.h" // for LayerManager::AddRef, etc |
|
20 |
|
21 namespace mozilla { |
|
22 namespace layers { |
|
23 |
|
24 class AsyncPanZoomController; |
|
25 class Layer; |
|
26 class LayerManagerComposite; |
|
27 class AutoResolveRefLayers; |
|
28 |
|
29 // Represents (affine) transforms that are calculated from a content view. |
|
30 struct ViewTransform { |
|
31 ViewTransform(LayerPoint aTranslation = LayerPoint(), |
|
32 ParentLayerToScreenScale aScale = ParentLayerToScreenScale()) |
|
33 : mTranslation(aTranslation) |
|
34 , mScale(aScale) |
|
35 {} |
|
36 |
|
37 operator gfx3DMatrix() const |
|
38 { |
|
39 return |
|
40 gfx3DMatrix::Translation(mTranslation.x, mTranslation.y, 0) * |
|
41 gfx3DMatrix::ScalingMatrix(mScale.scale, mScale.scale, 1); |
|
42 } |
|
43 |
|
44 bool operator==(const ViewTransform& rhs) const { |
|
45 return mTranslation == rhs.mTranslation && mScale == rhs.mScale; |
|
46 } |
|
47 |
|
48 bool operator!=(const ViewTransform& rhs) const { |
|
49 return !(*this == rhs); |
|
50 } |
|
51 |
|
52 LayerPoint mTranslation; |
|
53 ParentLayerToScreenScale mScale; |
|
54 }; |
|
55 |
|
56 /** |
|
57 * Manage async composition effects. This class is only used with OMTC and only |
|
58 * lives on the compositor thread. It is a layer on top of the layer manager |
|
59 * (LayerManagerComposite) which deals with elements of composition which are |
|
60 * usually dealt with by dom or layout when main thread rendering, but which can |
|
61 * short circuit that stuff to directly affect layers as they are composited, |
|
62 * for example, off-main thread animation, async video, async pan/zoom. |
|
63 */ |
|
64 class AsyncCompositionManager MOZ_FINAL |
|
65 { |
|
66 friend class AutoResolveRefLayers; |
|
67 public: |
|
68 NS_INLINE_DECL_REFCOUNTING(AsyncCompositionManager) |
|
69 |
|
70 AsyncCompositionManager(LayerManagerComposite* aManager) |
|
71 : mLayerManager(aManager) |
|
72 , mIsFirstPaint(false) |
|
73 , mLayersUpdated(false) |
|
74 , mReadyForCompose(true) |
|
75 { |
|
76 } |
|
77 ~AsyncCompositionManager() |
|
78 { |
|
79 } |
|
80 |
|
81 /** |
|
82 * This forces the is-first-paint flag to true. This is intended to |
|
83 * be called by the widget code when it loses its viewport information |
|
84 * (or for whatever reason wants to refresh the viewport information). |
|
85 * The information refresh happens because the compositor will call |
|
86 * SetFirstPaintViewport on the next frame of composition. |
|
87 */ |
|
88 void ForceIsFirstPaint() { mIsFirstPaint = true; } |
|
89 |
|
90 // Sample transforms for layer trees. Return true to request |
|
91 // another animation frame. |
|
92 bool TransformShadowTree(TimeStamp aCurrentFrame); |
|
93 |
|
94 // Calculates the correct rotation and applies the transform to |
|
95 // our layer manager |
|
96 void ComputeRotation(); |
|
97 |
|
98 // Call after updating our layer tree. |
|
99 void Updated(bool isFirstPaint, const TargetConfig& aTargetConfig) |
|
100 { |
|
101 mIsFirstPaint |= isFirstPaint; |
|
102 mLayersUpdated = true; |
|
103 mTargetConfig = aTargetConfig; |
|
104 } |
|
105 |
|
106 bool RequiresReorientation(mozilla::dom::ScreenOrientation aOrientation) |
|
107 { |
|
108 return mTargetConfig.orientation() != aOrientation; |
|
109 } |
|
110 |
|
111 // True if the underlying layer tree is ready to be composited. |
|
112 bool ReadyForCompose() { return mReadyForCompose; } |
|
113 |
|
114 // Returns true if the next composition will be the first for a |
|
115 // particular document. |
|
116 bool IsFirstPaint() { return mIsFirstPaint; } |
|
117 |
|
118 private: |
|
119 void TransformScrollableLayer(Layer* aLayer); |
|
120 // Return true if an AsyncPanZoomController content transform was |
|
121 // applied for |aLayer|. *aWantNextFrame is set to true if the |
|
122 // controller wants another animation frame. |
|
123 bool ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame, Layer* aLayer, |
|
124 bool* aWantNextFrame); |
|
125 /** |
|
126 * Update the shadow transform for aLayer assuming that is a scrollbar, |
|
127 * so that it stays in sync with the content that is being scrolled by APZ. |
|
128 */ |
|
129 void ApplyAsyncTransformToScrollbar(TimeStamp aCurrentFrame, ContainerLayer* aLayer); |
|
130 |
|
131 void SetFirstPaintViewport(const LayerIntPoint& aOffset, |
|
132 const CSSToLayerScale& aZoom, |
|
133 const CSSRect& aCssPageRect); |
|
134 void SetPageRect(const CSSRect& aCssPageRect); |
|
135 void SyncViewportInfo(const LayerIntRect& aDisplayPort, |
|
136 const CSSToLayerScale& aDisplayResolution, |
|
137 bool aLayersUpdated, |
|
138 ScreenPoint& aScrollOffset, |
|
139 CSSToScreenScale& aScale, |
|
140 LayerMargin& aFixedLayerMargins, |
|
141 ScreenPoint& aOffset); |
|
142 void SyncFrameMetrics(const ScreenPoint& aScrollOffset, |
|
143 float aZoom, |
|
144 const CSSRect& aCssPageRect, |
|
145 bool aLayersUpdated, |
|
146 const CSSRect& aDisplayPort, |
|
147 const CSSToLayerScale& aDisplayResolution, |
|
148 bool aIsFirstPaint, |
|
149 LayerMargin& aFixedLayerMargins, |
|
150 ScreenPoint& aOffset); |
|
151 |
|
152 /** |
|
153 * Adds a translation to the transform of any fixed position (whose parent |
|
154 * layer is not fixed) or sticky position layer descendant of |
|
155 * aTransformedSubtreeRoot. The translation is chosen so that the layer's |
|
156 * anchor point relative to aTransformedSubtreeRoot's parent layer is the same |
|
157 * as it was when aTransformedSubtreeRoot's GetLocalTransform() was |
|
158 * aPreviousTransformForRoot. For sticky position layers, the translation is |
|
159 * further intersected with the layer's sticky scroll ranges. |
|
160 * This function will also adjust layers so that the given content document |
|
161 * fixed position margins will be respected during asynchronous panning and |
|
162 * zooming. |
|
163 */ |
|
164 void AlignFixedAndStickyLayers(Layer* aLayer, Layer* aTransformedSubtreeRoot, |
|
165 const gfx::Matrix4x4& aPreviousTransformForRoot, |
|
166 const LayerMargin& aFixedLayerMargins); |
|
167 |
|
168 /** |
|
169 * DRAWING PHASE ONLY |
|
170 * |
|
171 * For reach RefLayer in our layer tree, look up its referent and connect it |
|
172 * to the layer tree, if found. |
|
173 */ |
|
174 void ResolveRefLayers(); |
|
175 /** |
|
176 * Detaches all referents resolved by ResolveRefLayers. |
|
177 * Assumes that mLayerManager->GetRoot() and mTargetConfig have not changed |
|
178 * since ResolveRefLayers was called. |
|
179 */ |
|
180 void DetachRefLayers(); |
|
181 |
|
182 TargetConfig mTargetConfig; |
|
183 CSSRect mContentRect; |
|
184 |
|
185 nsRefPtr<LayerManagerComposite> mLayerManager; |
|
186 // When this flag is set, the next composition will be the first for a |
|
187 // particular document (i.e. the document displayed on the screen will change). |
|
188 // This happens when loading a new page or switching tabs. We notify the |
|
189 // front-end (e.g. Java on Android) about this so that it take the new page |
|
190 // size and zoom into account when providing us with the next view transform. |
|
191 bool mIsFirstPaint; |
|
192 |
|
193 // This flag is set during a layers update, so that the first composition |
|
194 // after a layers update has it set. It is cleared after that first composition. |
|
195 bool mLayersUpdated; |
|
196 |
|
197 bool mReadyForCompose; |
|
198 }; |
|
199 |
|
200 class MOZ_STACK_CLASS AutoResolveRefLayers { |
|
201 public: |
|
202 AutoResolveRefLayers(AsyncCompositionManager* aManager) : mManager(aManager) |
|
203 { |
|
204 if (mManager) { |
|
205 mManager->ResolveRefLayers(); |
|
206 } |
|
207 } |
|
208 |
|
209 ~AutoResolveRefLayers() |
|
210 { |
|
211 if (mManager) { |
|
212 mManager->DetachRefLayers(); |
|
213 } |
|
214 } |
|
215 |
|
216 private: |
|
217 AsyncCompositionManager* mManager; |
|
218 |
|
219 AutoResolveRefLayers(const AutoResolveRefLayers&) MOZ_DELETE; |
|
220 AutoResolveRefLayers& operator=(const AutoResolveRefLayers&) MOZ_DELETE; |
|
221 }; |
|
222 |
|
223 } // layers |
|
224 } // mozilla |
|
225 |
|
226 #endif |