/src/mozilla-central/gfx/layers/FrameMetrics.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_FRAMEMETRICS_H |
8 | | #define GFX_FRAMEMETRICS_H |
9 | | |
10 | | #include <stdint.h> // for uint8_t, uint32_t, uint64_t |
11 | | #include <map> |
12 | | #include "Units.h" // for CSSRect, CSSPixel, etc |
13 | | #include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM |
14 | | #include "mozilla/HashFunctions.h" // for HashGeneric |
15 | | #include "mozilla/Maybe.h" |
16 | | #include "mozilla/gfx/BasePoint.h" // for BasePoint |
17 | | #include "mozilla/gfx/Rect.h" // for RoundedIn |
18 | | #include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor |
19 | | #include "mozilla/gfx/Logging.h" // for Log |
20 | | #include "mozilla/layers/LayersTypes.h" // for ScrollDirection |
21 | | #include "mozilla/StaticPtr.h" // for StaticAutoPtr |
22 | | #include "mozilla/TimeStamp.h" // for TimeStamp |
23 | | #include "nsString.h" |
24 | | #include "nsStyleCoord.h" // for nsStyleCoord |
25 | | #include "PLDHashTable.h" // for PLDHashNumber |
26 | | |
27 | | namespace IPC { |
28 | | template <typename T> struct ParamTraits; |
29 | | } // namespace IPC |
30 | | |
31 | | namespace mozilla { |
32 | | namespace layers { |
33 | | |
34 | | /** |
35 | | * Helper struct to hold a couple of fields that can be updated as part of |
36 | | * an empty transaction. |
37 | | */ |
38 | | struct ScrollUpdateInfo { |
39 | | uint32_t mScrollGeneration; |
40 | | CSSPoint mScrollOffset; |
41 | | }; |
42 | | |
43 | | /** |
44 | | * The viewport and displayport metrics for the painted frame at the |
45 | | * time of a layer-tree transaction. These metrics are especially |
46 | | * useful for shadow layers, because the metrics values are updated |
47 | | * atomically with new pixels. |
48 | | */ |
49 | | struct FrameMetrics { |
50 | | friend struct IPC::ParamTraits<mozilla::layers::FrameMetrics>; |
51 | | public: |
52 | | // We use IDs to identify frames across processes. |
53 | | typedef uint64_t ViewID; |
54 | | static const ViewID NULL_SCROLL_ID; // This container layer does not scroll. |
55 | | static const ViewID START_SCROLL_ID = 2; // This is the ID that scrolling subframes |
56 | | // will begin at. |
57 | | |
58 | | MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE( |
59 | | ScrollOffsetUpdateType, uint8_t, ( |
60 | | eNone, // The default; the scroll offset was not updated |
61 | | eMainThread, // The scroll offset was updated by the main thread. |
62 | | ePending, // The scroll offset was updated on the main thread, but not |
63 | | // painted, so the layer texture data is still at the old |
64 | | // offset. |
65 | | eUserAction, // In an APZ repaint request, this means the APZ generated |
66 | | // the scroll position based on user action (the alternative |
67 | | // is eNone which means it's just request a repaint because |
68 | | // it got a scroll update from the main thread). |
69 | | eRestore // The scroll offset was updated by the main thread, but as |
70 | | // a restore from history or after a frame reconstruction. |
71 | | // In this case, APZ can ignore the offset change if the |
72 | | // user has done an APZ scroll already. |
73 | | )); |
74 | | |
75 | | FrameMetrics() |
76 | | : mScrollId(NULL_SCROLL_ID) |
77 | | , mPresShellResolution(1) |
78 | | , mCompositionBounds(0, 0, 0, 0) |
79 | | , mDisplayPort(0, 0, 0, 0) |
80 | | , mCriticalDisplayPort(0, 0, 0, 0) |
81 | | , mScrollableRect(0, 0, 0, 0) |
82 | | , mCumulativeResolution() |
83 | | , mDevPixelsPerCSSPixel(1) |
84 | | , mScrollOffset(0, 0) |
85 | | , mZoom() |
86 | | , mScrollGeneration(0) |
87 | | , mSmoothScrollOffset(0, 0) |
88 | | , mRootCompositionSize(0, 0) |
89 | | , mDisplayPortMargins(0, 0, 0, 0) |
90 | | , mPresShellId(-1) |
91 | | , mViewport(0, 0, 0, 0) |
92 | | , mExtraResolution() |
93 | | , mPaintRequestTime() |
94 | | , mScrollUpdateType(eNone) |
95 | | , mIsRootContent(false) |
96 | | , mDoSmoothScroll(false) |
97 | | , mUseDisplayPortMargins(false) |
98 | | , mIsScrollInfoLayer(false) |
99 | | { |
100 | | } |
101 | | |
102 | | // Default copy ctor and operator= are fine |
103 | | |
104 | | bool operator==(const FrameMetrics& aOther) const |
105 | | { |
106 | | // Put mScrollId at the top since it's the most likely one to fail. |
107 | | return mScrollId == aOther.mScrollId && |
108 | | mPresShellResolution == aOther.mPresShellResolution && |
109 | | mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) && |
110 | | mDisplayPort.IsEqualEdges(aOther.mDisplayPort) && |
111 | | mCriticalDisplayPort.IsEqualEdges(aOther.mCriticalDisplayPort) && |
112 | | mScrollableRect.IsEqualEdges(aOther.mScrollableRect) && |
113 | | mCumulativeResolution == aOther.mCumulativeResolution && |
114 | | mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel && |
115 | | mScrollOffset == aOther.mScrollOffset && |
116 | | // don't compare mZoom |
117 | | mScrollGeneration == aOther.mScrollGeneration && |
118 | | mSmoothScrollOffset == aOther.mSmoothScrollOffset && |
119 | | mRootCompositionSize == aOther.mRootCompositionSize && |
120 | | mDisplayPortMargins == aOther.mDisplayPortMargins && |
121 | | mPresShellId == aOther.mPresShellId && |
122 | | mViewport.IsEqualEdges(aOther.mViewport) && |
123 | | mExtraResolution == aOther.mExtraResolution && |
124 | | mPaintRequestTime == aOther.mPaintRequestTime && |
125 | | mScrollUpdateType == aOther.mScrollUpdateType && |
126 | | mIsRootContent == aOther.mIsRootContent && |
127 | | mDoSmoothScroll == aOther.mDoSmoothScroll && |
128 | | mUseDisplayPortMargins == aOther.mUseDisplayPortMargins && |
129 | | mIsScrollInfoLayer == aOther.mIsScrollInfoLayer; |
130 | | } |
131 | | |
132 | | bool operator!=(const FrameMetrics& aOther) const |
133 | | { |
134 | | return !operator==(aOther); |
135 | | } |
136 | | |
137 | | bool IsScrollable() const |
138 | | { |
139 | | return mScrollId != NULL_SCROLL_ID; |
140 | | } |
141 | | |
142 | | CSSToScreenScale2D DisplayportPixelsPerCSSPixel() const |
143 | 0 | { |
144 | 0 | // Note: use 'mZoom * ParentLayerToLayerScale(1.0f)' as the CSS-to-Layer scale |
145 | 0 | // instead of LayersPixelsPerCSSPixel(), because displayport calculations |
146 | 0 | // are done in the context of a repaint request, where we ask Layout to |
147 | 0 | // repaint at a new resolution that includes any async zoom. Until this |
148 | 0 | // repaint request is processed, LayersPixelsPerCSSPixel() does not yet |
149 | 0 | // include the async zoom, but it will when the displayport is interpreted |
150 | 0 | // for the repaint. |
151 | 0 | return mZoom * ParentLayerToLayerScale(1.0f) / mExtraResolution; |
152 | 0 | } |
153 | | |
154 | | CSSToLayerScale2D LayersPixelsPerCSSPixel() const |
155 | 0 | { |
156 | 0 | return mDevPixelsPerCSSPixel * mCumulativeResolution; |
157 | 0 | } |
158 | | |
159 | | // Get the amount by which this frame has been zoomed since the last repaint. |
160 | | LayerToParentLayerScale GetAsyncZoom() const |
161 | | { |
162 | | // The async portion of the zoom should be the same along the x and y |
163 | | // axes. |
164 | | return (mZoom / LayersPixelsPerCSSPixel()).ToScaleFactor(); |
165 | | } |
166 | | |
167 | | // Ensure the scrollableRect is at least as big as the compositionBounds |
168 | | // because the scrollableRect can be smaller if the content is not large |
169 | | // and the scrollableRect hasn't been updated yet. |
170 | | // We move the scrollableRect up because we don't know if we can move it |
171 | | // down. i.e. we know that scrollableRect can go back as far as zero. |
172 | | // but we don't know how much further ahead it can go. |
173 | | CSSRect GetExpandedScrollableRect() const |
174 | | { |
175 | | CSSRect scrollableRect = mScrollableRect; |
176 | | CSSSize compSize = CalculateCompositedSizeInCssPixels(); |
177 | | if (scrollableRect.Width() < compSize.width) { |
178 | | scrollableRect.SetRectX(std::max(0.f, |
179 | | scrollableRect.X() - (compSize.width - scrollableRect.Width())), |
180 | | compSize.width); |
181 | | } |
182 | | |
183 | | if (scrollableRect.Height() < compSize.height) { |
184 | | scrollableRect.SetRectY(std::max(0.f, |
185 | | scrollableRect.Y() - (compSize.height - scrollableRect.Height())), |
186 | | compSize.height); |
187 | | } |
188 | | |
189 | | return scrollableRect; |
190 | | } |
191 | | |
192 | | CSSSize CalculateCompositedSizeInCssPixels() const |
193 | 0 | { |
194 | 0 | if (GetZoom() == CSSToParentLayerScale2D(0, 0)) { |
195 | 0 | return CSSSize(); // avoid division by zero |
196 | 0 | } |
197 | 0 | return mCompositionBounds.Size() / GetZoom(); |
198 | 0 | } |
199 | | |
200 | | /* |
201 | | * Calculate the composition bounds of this frame in the CSS pixels of |
202 | | * the content surrounding the scroll frame. (This can be thought of as |
203 | | * "parent CSS" pixels). |
204 | | * Note that it does not make to ask for the composition bounds in the |
205 | | * CSS pixels of the scrolled content (that is, regular CSS pixels), |
206 | | * because the origin of the composition bounds is not meaningful in that |
207 | | * coordinate space. (The size is, use CalculateCompositedSizeInCssPixels() |
208 | | * for that.) |
209 | | */ |
210 | | CSSRect CalculateCompositionBoundsInCssPixelsOfSurroundingContent() const |
211 | 0 | { |
212 | 0 | if (GetZoom() == CSSToParentLayerScale2D(0, 0)) { |
213 | 0 | return CSSRect(); // avoid division by zero |
214 | 0 | } |
215 | 0 | // The CSS pixels of the scrolled content and the CSS pixels of the |
216 | 0 | // surrounding content only differ if the scrolled content is rendered |
217 | 0 | // at a higher resolution, and the difference is the resolution. |
218 | 0 | return mCompositionBounds / GetZoom() * CSSToCSSScale{mPresShellResolution}; |
219 | 0 | } |
220 | | |
221 | | CSSSize CalculateBoundedCompositedSizeInCssPixels() const |
222 | 0 | { |
223 | 0 | CSSSize size = CalculateCompositedSizeInCssPixels(); |
224 | 0 | size.width = std::min(size.width, mRootCompositionSize.width); |
225 | 0 | size.height = std::min(size.height, mRootCompositionSize.height); |
226 | 0 | return size; |
227 | 0 | } |
228 | | |
229 | | CSSRect CalculateScrollRange() const |
230 | 0 | { |
231 | 0 | CSSSize scrollPortSize = CalculateCompositedSizeInCssPixels(); |
232 | 0 | CSSRect scrollRange = mScrollableRect; |
233 | 0 | scrollRange.SetWidth(std::max(scrollRange.Width() - scrollPortSize.width, 0.0f)); |
234 | 0 | scrollRange.SetHeight(std::max(scrollRange.Height() - scrollPortSize.height, 0.0f)); |
235 | 0 | return scrollRange; |
236 | 0 | } |
237 | | |
238 | | void ScrollBy(const CSSPoint& aPoint) |
239 | 0 | { |
240 | 0 | mScrollOffset += aPoint; |
241 | 0 | } |
242 | | |
243 | | void ZoomBy(float aScale) |
244 | 0 | { |
245 | 0 | ZoomBy(gfxSize(aScale, aScale)); |
246 | 0 | } |
247 | | |
248 | | void ZoomBy(const gfxSize& aScale) |
249 | 0 | { |
250 | 0 | mZoom.xScale *= aScale.width; |
251 | 0 | mZoom.yScale *= aScale.height; |
252 | 0 | } |
253 | | |
254 | | void CopyScrollInfoFrom(const FrameMetrics& aOther) |
255 | 0 | { |
256 | 0 | mScrollOffset = aOther.mScrollOffset; |
257 | 0 | mScrollGeneration = aOther.mScrollGeneration; |
258 | 0 | } |
259 | | |
260 | | void CopySmoothScrollInfoFrom(const FrameMetrics& aOther) |
261 | 0 | { |
262 | 0 | mSmoothScrollOffset = aOther.mSmoothScrollOffset; |
263 | 0 | mScrollGeneration = aOther.mScrollGeneration; |
264 | 0 | mDoSmoothScroll = aOther.mDoSmoothScroll; |
265 | 0 | } |
266 | | |
267 | | void UpdatePendingScrollInfo(const ScrollUpdateInfo& aInfo) |
268 | | { |
269 | | mScrollOffset = aInfo.mScrollOffset; |
270 | | mScrollGeneration = aInfo.mScrollGeneration; |
271 | | mScrollUpdateType = ePending; |
272 | | } |
273 | | |
274 | | void SetRepaintDrivenByUserAction(bool aUserAction) |
275 | 0 | { |
276 | 0 | mScrollUpdateType = aUserAction ? eUserAction : eNone; |
277 | 0 | } |
278 | | |
279 | | public: |
280 | | void SetPresShellResolution(float aPresShellResolution) |
281 | 0 | { |
282 | 0 | mPresShellResolution = aPresShellResolution; |
283 | 0 | } |
284 | | |
285 | | float GetPresShellResolution() const |
286 | | { |
287 | | return mPresShellResolution; |
288 | | } |
289 | | |
290 | | void SetCompositionBounds(const ParentLayerRect& aCompositionBounds) |
291 | 0 | { |
292 | 0 | mCompositionBounds = aCompositionBounds; |
293 | 0 | } |
294 | | |
295 | | const ParentLayerRect& GetCompositionBounds() const |
296 | | { |
297 | | return mCompositionBounds; |
298 | | } |
299 | | |
300 | | void SetDisplayPort(const CSSRect& aDisplayPort) |
301 | | { |
302 | | mDisplayPort = aDisplayPort; |
303 | | } |
304 | | |
305 | | const CSSRect& GetDisplayPort() const |
306 | | { |
307 | | return mDisplayPort; |
308 | | } |
309 | | |
310 | | void SetCriticalDisplayPort(const CSSRect& aCriticalDisplayPort) |
311 | | { |
312 | | mCriticalDisplayPort = aCriticalDisplayPort; |
313 | | } |
314 | | |
315 | | const CSSRect& GetCriticalDisplayPort() const |
316 | | { |
317 | | return mCriticalDisplayPort; |
318 | | } |
319 | | |
320 | | void SetCumulativeResolution(const LayoutDeviceToLayerScale2D& aCumulativeResolution) |
321 | 0 | { |
322 | 0 | mCumulativeResolution = aCumulativeResolution; |
323 | 0 | } |
324 | | |
325 | | const LayoutDeviceToLayerScale2D& GetCumulativeResolution() const |
326 | | { |
327 | | return mCumulativeResolution; |
328 | | } |
329 | | |
330 | | void SetDevPixelsPerCSSPixel(const CSSToLayoutDeviceScale& aDevPixelsPerCSSPixel) |
331 | 0 | { |
332 | 0 | mDevPixelsPerCSSPixel = aDevPixelsPerCSSPixel; |
333 | 0 | } |
334 | | |
335 | | const CSSToLayoutDeviceScale& GetDevPixelsPerCSSPixel() const |
336 | | { |
337 | | return mDevPixelsPerCSSPixel; |
338 | | } |
339 | | |
340 | | void SetIsRootContent(bool aIsRootContent) |
341 | | { |
342 | | mIsRootContent = aIsRootContent; |
343 | | } |
344 | | |
345 | | bool IsRootContent() const |
346 | | { |
347 | | return mIsRootContent; |
348 | | } |
349 | | |
350 | | void SetScrollOffset(const CSSPoint& aScrollOffset) |
351 | 0 | { |
352 | 0 | mScrollOffset = aScrollOffset; |
353 | 0 | } |
354 | | |
355 | | // Set scroll offset, first clamping to the scroll range. |
356 | | void ClampAndSetScrollOffset(const CSSPoint& aScrollOffset) |
357 | 0 | { |
358 | 0 | SetScrollOffset(CalculateScrollRange().ClampPoint(aScrollOffset)); |
359 | 0 | } |
360 | | |
361 | | const CSSPoint& GetScrollOffset() const |
362 | | { |
363 | | return mScrollOffset; |
364 | | } |
365 | | |
366 | | void SetSmoothScrollOffset(const CSSPoint& aSmoothScrollDestination) |
367 | | { |
368 | | mSmoothScrollOffset = aSmoothScrollDestination; |
369 | | } |
370 | | |
371 | | const CSSPoint& GetSmoothScrollOffset() const |
372 | | { |
373 | | return mSmoothScrollOffset; |
374 | | } |
375 | | |
376 | | void SetZoom(const CSSToParentLayerScale2D& aZoom) |
377 | 0 | { |
378 | 0 | mZoom = aZoom; |
379 | 0 | } |
380 | | |
381 | | const CSSToParentLayerScale2D& GetZoom() const |
382 | 0 | { |
383 | 0 | return mZoom; |
384 | 0 | } |
385 | | |
386 | | void SetScrollOffsetUpdated(uint32_t aScrollGeneration) |
387 | | { |
388 | | mScrollUpdateType = eMainThread; |
389 | | mScrollGeneration = aScrollGeneration; |
390 | | } |
391 | | |
392 | | void SetScrollOffsetRestored(uint32_t aScrollGeneration) |
393 | | { |
394 | | mScrollUpdateType = eRestore; |
395 | | mScrollGeneration = aScrollGeneration; |
396 | | } |
397 | | |
398 | | void SetSmoothScrollOffsetUpdated(int32_t aScrollGeneration) |
399 | | { |
400 | | mDoSmoothScroll = true; |
401 | | mScrollGeneration = aScrollGeneration; |
402 | | } |
403 | | |
404 | | ScrollOffsetUpdateType GetScrollUpdateType() const |
405 | | { |
406 | | return mScrollUpdateType; |
407 | | } |
408 | | |
409 | | bool GetScrollOffsetUpdated() const |
410 | 0 | { |
411 | 0 | return mScrollUpdateType != eNone; |
412 | 0 | } |
413 | | |
414 | | bool GetDoSmoothScroll() const |
415 | | { |
416 | | return mDoSmoothScroll; |
417 | | } |
418 | | |
419 | | uint32_t GetScrollGeneration() const |
420 | | { |
421 | | return mScrollGeneration; |
422 | | } |
423 | | |
424 | | ViewID GetScrollId() const |
425 | | { |
426 | | return mScrollId; |
427 | | } |
428 | | |
429 | | void SetScrollId(ViewID scrollId) |
430 | | { |
431 | | mScrollId = scrollId; |
432 | | } |
433 | | |
434 | | void SetRootCompositionSize(const CSSSize& aRootCompositionSize) |
435 | 0 | { |
436 | 0 | mRootCompositionSize = aRootCompositionSize; |
437 | 0 | } |
438 | | |
439 | | const CSSSize& GetRootCompositionSize() const |
440 | | { |
441 | | return mRootCompositionSize; |
442 | | } |
443 | | |
444 | | void SetDisplayPortMargins(const ScreenMargin& aDisplayPortMargins) |
445 | 0 | { |
446 | 0 | mDisplayPortMargins = aDisplayPortMargins; |
447 | 0 | } |
448 | | |
449 | | const ScreenMargin& GetDisplayPortMargins() const |
450 | | { |
451 | | return mDisplayPortMargins; |
452 | | } |
453 | | |
454 | | void SetUseDisplayPortMargins(bool aValue) |
455 | | { |
456 | | mUseDisplayPortMargins = aValue; |
457 | | } |
458 | | |
459 | | bool GetUseDisplayPortMargins() const |
460 | | { |
461 | | return mUseDisplayPortMargins; |
462 | | } |
463 | | |
464 | | uint32_t GetPresShellId() const |
465 | | { |
466 | | return mPresShellId; |
467 | | } |
468 | | |
469 | | void SetPresShellId(uint32_t aPresShellId) |
470 | | { |
471 | | mPresShellId = aPresShellId; |
472 | | } |
473 | | |
474 | | void SetViewport(const CSSRect& aViewport) |
475 | 0 | { |
476 | 0 | mViewport = aViewport; |
477 | 0 | } |
478 | | |
479 | | const CSSRect& GetViewport() const |
480 | | { |
481 | | return mViewport; |
482 | | } |
483 | | |
484 | | CSSRect GetVisualViewport() const |
485 | 0 | { |
486 | 0 | return CSSRect(mScrollOffset, CalculateCompositedSizeInCssPixels()); |
487 | 0 | } |
488 | | |
489 | | void SetExtraResolution(const ScreenToLayerScale2D& aExtraResolution) |
490 | | { |
491 | | mExtraResolution = aExtraResolution; |
492 | | } |
493 | | |
494 | | const ScreenToLayerScale2D& GetExtraResolution() const |
495 | | { |
496 | | return mExtraResolution; |
497 | | } |
498 | | |
499 | | const CSSRect& GetScrollableRect() const |
500 | | { |
501 | | return mScrollableRect; |
502 | | } |
503 | | |
504 | | void SetScrollableRect(const CSSRect& aScrollableRect) |
505 | 0 | { |
506 | 0 | mScrollableRect = aScrollableRect; |
507 | 0 | } |
508 | | |
509 | | // If the frame is in vertical-RTL writing mode(E.g. "writing-mode: |
510 | | // vertical-rl" in CSS), or if it's in horizontal-RTL writing-mode(E.g. |
511 | | // "writing-mode: horizontal-tb; direction: rtl;" in CSS), then this function |
512 | | // returns true. From the representation perspective, frames whose horizontal |
513 | | // contents start at rightside also cause their horizontal scrollbars, if any, |
514 | | // initially start at rightside. So we can also learn about the initial side |
515 | | // of the horizontal scrollbar for the frame by calling this function. |
516 | 0 | bool IsHorizontalContentRightToLeft() const { |
517 | 0 | return mScrollableRect.x < 0; |
518 | 0 | } |
519 | | |
520 | 0 | void SetPaintRequestTime(const TimeStamp& aTime) { |
521 | 0 | mPaintRequestTime = aTime; |
522 | 0 | } |
523 | 0 | const TimeStamp& GetPaintRequestTime() const { |
524 | 0 | return mPaintRequestTime; |
525 | 0 | } |
526 | | |
527 | | void SetIsScrollInfoLayer(bool aIsScrollInfoLayer) { |
528 | | mIsScrollInfoLayer = aIsScrollInfoLayer; |
529 | | } |
530 | 0 | bool IsScrollInfoLayer() const { |
531 | 0 | return mIsScrollInfoLayer; |
532 | 0 | } |
533 | | |
534 | | // Determine if the visual viewport is outside of the layout viewport and |
535 | | // adjust the x,y-offset in mViewport accordingly. This is necessary to |
536 | | // allow APZ to async-scroll the layout viewport. |
537 | | // |
538 | | // This is a no-op if mIsRootContent is false. |
539 | | void RecalculateViewportOffset(); |
540 | | |
541 | | private: |
542 | | // A unique ID assigned to each scrollable frame. |
543 | | ViewID mScrollId; |
544 | | |
545 | | // The pres-shell resolution that has been induced on the document containing |
546 | | // this scroll frame as a result of zooming this scroll frame (whether via |
547 | | // user action, or choosing an initial zoom level on page load). This can |
548 | | // only be different from 1.0 for frames that are zoomable, which currently |
549 | | // is just the root content document's root scroll frame (mIsRoot = true). |
550 | | // This is a plain float rather than a ScaleFactor because in and of itself |
551 | | // it does not convert between any coordinate spaces for which we have names. |
552 | | float mPresShellResolution; |
553 | | |
554 | | // This is the area within the widget that we're compositing to. It is in the |
555 | | // same coordinate space as the reference frame for the scrolled frame. |
556 | | // |
557 | | // This is useful because, on mobile, the viewport and composition dimensions |
558 | | // are not always the same. In this case, we calculate the displayport using |
559 | | // an area bigger than the region we're compositing to. If we used the |
560 | | // viewport dimensions to calculate the displayport, we'd run into situations |
561 | | // where we're prerendering the wrong regions and the content may be clipped, |
562 | | // or too much of it prerendered. If the composition dimensions are the same |
563 | | // as the viewport dimensions, there is no need for this and we can just use |
564 | | // the viewport instead. |
565 | | // |
566 | | // This value is valid for nested scrollable layers as well, and is still |
567 | | // relative to the layer tree origin. This value is provided by Gecko at |
568 | | // layout/paint time. |
569 | | ParentLayerRect mCompositionBounds; |
570 | | |
571 | | // The area of a frame's contents that has been painted, relative to |
572 | | // mCompositionBounds. |
573 | | // |
574 | | // Note that this is structured in such a way that it doesn't depend on the |
575 | | // method layout uses to scroll content. |
576 | | // |
577 | | // May be larger or smaller than |mScrollableRect|. |
578 | | // |
579 | | // To pre-render a margin of 100 CSS pixels around the window, |
580 | | // { x = -100, y = - 100, |
581 | | // width = window.innerWidth + 200, height = window.innerHeight + 200 } |
582 | | CSSRect mDisplayPort; |
583 | | |
584 | | // If non-empty, the area of a frame's contents that is considered critical |
585 | | // to paint. Area outside of this area (i.e. area inside mDisplayPort, but |
586 | | // outside of mCriticalDisplayPort) is considered low-priority, and may be |
587 | | // painted with lower precision, or not painted at all. |
588 | | // |
589 | | // The same restrictions for mDisplayPort apply here. |
590 | | CSSRect mCriticalDisplayPort; |
591 | | |
592 | | // The scrollable bounds of a frame. This is determined by reflow. |
593 | | // Ordinarily the x and y will be 0 and the width and height will be the |
594 | | // size of the element being scrolled. However for RTL pages or elements |
595 | | // the x value may be negative. |
596 | | // |
597 | | // For scrollable frames that are overflow:hidden the x and y are usually |
598 | | // set to the value of the current scroll offset, and the width and height |
599 | | // will match the composition bounds width and height. In effect this reduces |
600 | | // the scrollable range to 0. |
601 | | // |
602 | | // This is in the same coordinate space as |mScrollOffset|, but a different |
603 | | // coordinate space than |mViewport| and |mDisplayPort|. Note also that this |
604 | | // coordinate system is understood by window.scrollTo(). |
605 | | // |
606 | | // This is valid on any layer unless it has no content. |
607 | | CSSRect mScrollableRect; |
608 | | |
609 | | // The cumulative resolution that the current frame has been painted at. |
610 | | // This is the product of the pres-shell resolutions of the document |
611 | | // containing this scroll frame and its ancestors, and any css-driven |
612 | | // resolution. This information is provided by Gecko at layout/paint time. |
613 | | // Note that this is allowed to have different x- and y-scales, but only |
614 | | // for subframes (mIsRoot = false). (The same applies to other scales that |
615 | | // "inherit" the 2D-ness of this one, such as mZoom.) |
616 | | LayoutDeviceToLayerScale2D mCumulativeResolution; |
617 | | |
618 | | // New fields from now on should be made private and old fields should |
619 | | // be refactored to be private. |
620 | | |
621 | | // The conversion factor between CSS pixels and device pixels for this frame. |
622 | | // This can vary based on a variety of things, such as reflowing-zoom. The |
623 | | // conversion factor for device pixels to layers pixels is just the |
624 | | // resolution. |
625 | | CSSToLayoutDeviceScale mDevPixelsPerCSSPixel; |
626 | | |
627 | | // The position of the top-left of the CSS viewport, relative to the document |
628 | | // (or the document relative to the viewport, if that helps understand it). |
629 | | // |
630 | | // Thus it is relative to the document. It is in the same coordinate space as |
631 | | // |mScrollableRect|, but a different coordinate space than |mViewport| and |
632 | | // |mDisplayPort|. |
633 | | // |
634 | | // It is required that the rect: |
635 | | // { x = mScrollOffset.x, y = mScrollOffset.y, |
636 | | // width = mCompositionBounds.x / mResolution.scale, |
637 | | // height = mCompositionBounds.y / mResolution.scale } |
638 | | // Be within |mScrollableRect|. |
639 | | // |
640 | | // This is valid for any layer, but is always relative to this frame and |
641 | | // not any parents, regardless of parent transforms. |
642 | | CSSPoint mScrollOffset; |
643 | | |
644 | | // The "user zoom". Content is painted by gecko at mResolution * mDevPixelsPerCSSPixel, |
645 | | // but will be drawn to the screen at mZoom. In the steady state, the |
646 | | // two will be the same, but during an async zoom action the two may |
647 | | // diverge. This information is initialized in Gecko but updated in the APZC. |
648 | | CSSToParentLayerScale2D mZoom; |
649 | | |
650 | | // The scroll generation counter used to acknowledge the scroll offset update. |
651 | | uint32_t mScrollGeneration; |
652 | | |
653 | | // If mDoSmoothScroll is true, the scroll offset will be animated smoothly |
654 | | // to this value. |
655 | | CSSPoint mSmoothScrollOffset; |
656 | | |
657 | | // The size of the root scrollable's composition bounds, but in local CSS pixels. |
658 | | CSSSize mRootCompositionSize; |
659 | | |
660 | | // A display port expressed as layer margins that apply to the rect of what |
661 | | // is drawn of the scrollable element. |
662 | | ScreenMargin mDisplayPortMargins; |
663 | | |
664 | | uint32_t mPresShellId; |
665 | | |
666 | | // The CSS viewport, which is the dimensions we're using to constrain the |
667 | | // <html> element of this frame, relative to the top-left of the layer. Note |
668 | | // that its offset is structured in such a way that it doesn't depend on the |
669 | | // method layout uses to scroll content. |
670 | | // |
671 | | // This is mainly useful on the root layer, however nested iframes can have |
672 | | // their own viewport, which will just be the size of the window of the |
673 | | // iframe. For layers that don't correspond to a document, this metric is |
674 | | // meaningless and invalid. |
675 | | CSSRect mViewport; |
676 | | |
677 | | // The extra resolution at which content in this scroll frame is drawn beyond |
678 | | // that necessary to draw one Layer pixel per Screen pixel. |
679 | | ScreenToLayerScale2D mExtraResolution; |
680 | | |
681 | | // The time at which the APZC last requested a repaint for this scrollframe. |
682 | | TimeStamp mPaintRequestTime; |
683 | | |
684 | | // Whether mScrollOffset was updated by something other than the APZ code, and |
685 | | // if the APZC receiving this metrics should update its local copy. |
686 | | ScrollOffsetUpdateType mScrollUpdateType; |
687 | | |
688 | | // Whether or not this is the root scroll frame for the root content document. |
689 | | bool mIsRootContent:1; |
690 | | |
691 | | // When mDoSmoothScroll, the scroll offset should be animated to |
692 | | // smoothly transition to mScrollOffset rather than be updated instantly. |
693 | | bool mDoSmoothScroll:1; |
694 | | |
695 | | // If this is true then we use the display port margins on this metrics, |
696 | | // otherwise use the display port rect. |
697 | | bool mUseDisplayPortMargins:1; |
698 | | |
699 | | // Whether or not this frame has a "scroll info layer" to capture events. |
700 | | bool mIsScrollInfoLayer:1; |
701 | | |
702 | | // WARNING!!!! |
703 | | // |
704 | | // When adding a new field: |
705 | | // |
706 | | // - First, consider whether the field can be added to ScrollMetadata |
707 | | // instead. If so, prefer that. |
708 | | // |
709 | | // - Otherwise, the following places should be updated to include them |
710 | | // (as needed): |
711 | | // FrameMetrics::operator == |
712 | | // AsyncPanZoomController::NotifyLayersUpdated |
713 | | // The ParamTraits specialization in GfxMessageUtils.h |
714 | | // |
715 | | // Please add new fields above this comment. |
716 | | |
717 | | // Private helpers for IPC purposes |
718 | | void SetDoSmoothScroll(bool aValue) { |
719 | | mDoSmoothScroll = aValue; |
720 | | } |
721 | | }; |
722 | | |
723 | | struct ScrollSnapInfo { |
724 | | ScrollSnapInfo() |
725 | | : mScrollSnapTypeX(NS_STYLE_SCROLL_SNAP_TYPE_NONE) |
726 | | , mScrollSnapTypeY(NS_STYLE_SCROLL_SNAP_TYPE_NONE) |
727 | | {} |
728 | | |
729 | | bool operator==(const ScrollSnapInfo& aOther) const |
730 | | { |
731 | | return mScrollSnapTypeX == aOther.mScrollSnapTypeX && |
732 | | mScrollSnapTypeY == aOther.mScrollSnapTypeY && |
733 | | mScrollSnapIntervalX == aOther.mScrollSnapIntervalX && |
734 | | mScrollSnapIntervalY == aOther.mScrollSnapIntervalY && |
735 | | mScrollSnapDestination == aOther.mScrollSnapDestination && |
736 | | mScrollSnapCoordinates == aOther.mScrollSnapCoordinates; |
737 | | } |
738 | | |
739 | | bool HasScrollSnapping() const |
740 | | { |
741 | | return mScrollSnapTypeY != NS_STYLE_SCROLL_SNAP_TYPE_NONE || |
742 | | mScrollSnapTypeX != NS_STYLE_SCROLL_SNAP_TYPE_NONE; |
743 | | } |
744 | | |
745 | | // The scroll frame's scroll-snap-type. |
746 | | // One of NS_STYLE_SCROLL_SNAP_{NONE, MANDATORY, PROXIMITY}. |
747 | | uint8_t mScrollSnapTypeX; |
748 | | uint8_t mScrollSnapTypeY; |
749 | | |
750 | | // The intervals derived from the scroll frame's scroll-snap-points. |
751 | | Maybe<nscoord> mScrollSnapIntervalX; |
752 | | Maybe<nscoord> mScrollSnapIntervalY; |
753 | | |
754 | | // The scroll frame's scroll-snap-destination, in cooked form (to avoid |
755 | | // shipping the raw nsStyleCoord::CalcValue over IPC). |
756 | | nsPoint mScrollSnapDestination; |
757 | | |
758 | | // The scroll-snap-coordinates of any descendant frames of the scroll frame, |
759 | | // relative to the origin of the scrolled frame. |
760 | | nsTArray<nsPoint> mScrollSnapCoordinates; |
761 | | }; |
762 | | |
763 | | MOZ_DEFINE_ENUM_CLASS_WITH_BASE( |
764 | | OverscrollBehavior, uint8_t, ( |
765 | | Auto, |
766 | | Contain, |
767 | | None |
768 | | )); |
769 | | |
770 | | struct OverscrollBehaviorInfo { |
771 | | OverscrollBehaviorInfo() |
772 | | : mBehaviorX(OverscrollBehavior::Auto) |
773 | | , mBehaviorY(OverscrollBehavior::Auto) |
774 | | {} |
775 | | |
776 | | // Construct from StyleOverscrollBehavior values. |
777 | | static OverscrollBehaviorInfo FromStyleConstants(StyleOverscrollBehavior aBehaviorX, |
778 | | StyleOverscrollBehavior aBehaviorY); |
779 | | |
780 | | bool operator==(const OverscrollBehaviorInfo& aOther) const { |
781 | | return mBehaviorX == aOther.mBehaviorX && |
782 | | mBehaviorY == aOther.mBehaviorY; |
783 | | } |
784 | | |
785 | | OverscrollBehavior mBehaviorX; |
786 | | OverscrollBehavior mBehaviorY; |
787 | | }; |
788 | | |
789 | | /** |
790 | | * A clip that applies to a layer, that may be scrolled by some of the |
791 | | * scroll frames associated with the layer. |
792 | | */ |
793 | | struct LayerClip { |
794 | | friend struct IPC::ParamTraits<mozilla::layers::LayerClip>; |
795 | | |
796 | | public: |
797 | | LayerClip() |
798 | | : mClipRect() |
799 | | , mMaskLayerIndex() |
800 | | {} |
801 | | |
802 | | explicit LayerClip(const ParentLayerIntRect& aClipRect) |
803 | | : mClipRect(aClipRect) |
804 | | , mMaskLayerIndex() |
805 | | {} |
806 | | |
807 | | bool operator==(const LayerClip& aOther) const |
808 | | { |
809 | | return mClipRect == aOther.mClipRect && |
810 | | mMaskLayerIndex == aOther.mMaskLayerIndex; |
811 | | } |
812 | | |
813 | | void SetClipRect(const ParentLayerIntRect& aClipRect) { |
814 | | mClipRect = aClipRect; |
815 | | } |
816 | | const ParentLayerIntRect& GetClipRect() const { |
817 | | return mClipRect; |
818 | | } |
819 | | |
820 | | void SetMaskLayerIndex(const Maybe<size_t>& aIndex) { |
821 | | mMaskLayerIndex = aIndex; |
822 | | } |
823 | | const Maybe<size_t>& GetMaskLayerIndex() const { |
824 | | return mMaskLayerIndex; |
825 | | } |
826 | | |
827 | | private: |
828 | | ParentLayerIntRect mClipRect; |
829 | | |
830 | | // Optionally, specifies a mask layer that's part of the clip. |
831 | | // This is an index into the MetricsMaskLayers array on the Layer. |
832 | | Maybe<size_t> mMaskLayerIndex; |
833 | | }; |
834 | | |
835 | | typedef Maybe<LayerClip> MaybeLayerClip; // for passing over IPDL |
836 | | |
837 | | /** |
838 | | * Metadata about a scroll frame that's stored in the layer tree for use by |
839 | | * the compositor (including APZ). This includes the scroll frame's FrameMetrics, |
840 | | * as well as other metadata. We don't put the other metadata into FrameMetrics |
841 | | * to avoid FrameMetrics becoming too bloated (as a FrameMetrics is e.g. sent |
842 | | * over IPC for every repaint request for every active scroll frame). |
843 | | */ |
844 | | struct ScrollMetadata { |
845 | | friend struct IPC::ParamTraits<mozilla::layers::ScrollMetadata>; |
846 | | |
847 | | typedef FrameMetrics::ViewID ViewID; |
848 | | public: |
849 | | static StaticAutoPtr<const ScrollMetadata> sNullMetadata; // We sometimes need an empty metadata |
850 | | |
851 | | ScrollMetadata() |
852 | | : mMetrics() |
853 | | , mSnapInfo() |
854 | | , mScrollParentId(FrameMetrics::NULL_SCROLL_ID) |
855 | | , mBackgroundColor() |
856 | | , mContentDescription() |
857 | | , mLineScrollAmount(0, 0) |
858 | | , mPageScrollAmount(0, 0) |
859 | | , mScrollClip() |
860 | | , mHasScrollgrab(false) |
861 | | , mIsLayersIdRoot(false) |
862 | | , mIsAutoDirRootContentRTL(false) |
863 | | , mUsesContainerScrolling(false) |
864 | | , mForceDisableApz(false) |
865 | | , mOverscrollBehavior() |
866 | | {} |
867 | | |
868 | | bool operator==(const ScrollMetadata& aOther) const |
869 | | { |
870 | | return mMetrics == aOther.mMetrics && |
871 | | mSnapInfo == aOther.mSnapInfo && |
872 | | mScrollParentId == aOther.mScrollParentId && |
873 | | mBackgroundColor == aOther.mBackgroundColor && |
874 | | // don't compare mContentDescription |
875 | | mLineScrollAmount == aOther.mLineScrollAmount && |
876 | | mPageScrollAmount == aOther.mPageScrollAmount && |
877 | | mScrollClip == aOther.mScrollClip && |
878 | | mHasScrollgrab == aOther.mHasScrollgrab && |
879 | | mIsLayersIdRoot == aOther.mIsLayersIdRoot && |
880 | | mIsAutoDirRootContentRTL == aOther.mIsAutoDirRootContentRTL && |
881 | | mUsesContainerScrolling == aOther.mUsesContainerScrolling && |
882 | | mForceDisableApz == aOther.mForceDisableApz && |
883 | | mDisregardedDirection == aOther.mDisregardedDirection && |
884 | | mOverscrollBehavior == aOther.mOverscrollBehavior; |
885 | | } |
886 | | |
887 | | bool operator!=(const ScrollMetadata& aOther) const |
888 | | { |
889 | | return !operator==(aOther); |
890 | | } |
891 | | |
892 | | bool IsDefault() const |
893 | | { |
894 | | ScrollMetadata def; |
895 | | |
896 | | def.mMetrics.SetPresShellId(mMetrics.GetPresShellId()); |
897 | | return (def == *this); |
898 | | } |
899 | | |
900 | | FrameMetrics& GetMetrics() { return mMetrics; } |
901 | | const FrameMetrics& GetMetrics() const { return mMetrics; } |
902 | | |
903 | 0 | void SetSnapInfo(ScrollSnapInfo&& aSnapInfo) { |
904 | 0 | mSnapInfo = std::move(aSnapInfo); |
905 | 0 | } |
906 | 0 | const ScrollSnapInfo& GetSnapInfo() const { return mSnapInfo; } |
907 | | |
908 | | ViewID GetScrollParentId() const { |
909 | | return mScrollParentId; |
910 | | } |
911 | | |
912 | 0 | void SetScrollParentId(ViewID aParentId) { |
913 | 0 | mScrollParentId = aParentId; |
914 | 0 | } |
915 | | const gfx::Color& GetBackgroundColor() const { |
916 | | return mBackgroundColor; |
917 | | } |
918 | | void SetBackgroundColor(const gfx::Color& aBackgroundColor) { |
919 | | mBackgroundColor = aBackgroundColor; |
920 | | } |
921 | | const nsCString& GetContentDescription() const { |
922 | | return mContentDescription; |
923 | | } |
924 | | void SetContentDescription(const nsCString& aContentDescription) { |
925 | | mContentDescription = aContentDescription; |
926 | | } |
927 | 0 | const LayoutDeviceIntSize& GetLineScrollAmount() const { |
928 | 0 | return mLineScrollAmount; |
929 | 0 | } |
930 | 0 | void SetLineScrollAmount(const LayoutDeviceIntSize& size) { |
931 | 0 | mLineScrollAmount = size; |
932 | 0 | } |
933 | 0 | const LayoutDeviceIntSize& GetPageScrollAmount() const { |
934 | 0 | return mPageScrollAmount; |
935 | 0 | } |
936 | 0 | void SetPageScrollAmount(const LayoutDeviceIntSize& size) { |
937 | 0 | mPageScrollAmount = size; |
938 | 0 | } |
939 | | |
940 | 0 | void SetScrollClip(const Maybe<LayerClip>& aScrollClip) { |
941 | 0 | mScrollClip = aScrollClip; |
942 | 0 | } |
943 | | const Maybe<LayerClip>& GetScrollClip() const { |
944 | | return mScrollClip; |
945 | | } |
946 | | bool HasScrollClip() const { |
947 | | return mScrollClip.isSome(); |
948 | | } |
949 | | const LayerClip& ScrollClip() const { |
950 | | return mScrollClip.ref(); |
951 | | } |
952 | | LayerClip& ScrollClip() { |
953 | | return mScrollClip.ref(); |
954 | | } |
955 | | |
956 | | bool HasMaskLayer() const { |
957 | | return HasScrollClip() && ScrollClip().GetMaskLayerIndex(); |
958 | | } |
959 | | Maybe<ParentLayerIntRect> GetClipRect() const { |
960 | | return mScrollClip.isSome() ? Some(mScrollClip->GetClipRect()) : Nothing(); |
961 | | } |
962 | | |
963 | | void SetHasScrollgrab(bool aHasScrollgrab) { |
964 | | mHasScrollgrab = aHasScrollgrab; |
965 | | } |
966 | 0 | bool GetHasScrollgrab() const { |
967 | 0 | return mHasScrollgrab; |
968 | 0 | } |
969 | | void SetIsLayersIdRoot(bool aValue) { |
970 | | mIsLayersIdRoot = aValue; |
971 | | } |
972 | 0 | bool IsLayersIdRoot() const { |
973 | 0 | return mIsLayersIdRoot; |
974 | 0 | } |
975 | | void SetIsAutoDirRootContentRTL(bool aValue) { |
976 | | mIsAutoDirRootContentRTL = aValue; |
977 | | } |
978 | 0 | bool IsAutoDirRootContentRTL() const { |
979 | 0 | return mIsAutoDirRootContentRTL; |
980 | 0 | } |
981 | | // Implemented out of line because the implementation needs gfxPrefs.h |
982 | | // and we don't want to include that from FrameMetrics.h. |
983 | | void SetUsesContainerScrolling(bool aValue); |
984 | 0 | bool UsesContainerScrolling() const { |
985 | 0 | return mUsesContainerScrolling; |
986 | 0 | } |
987 | | void SetForceDisableApz(bool aForceDisable) { |
988 | | mForceDisableApz = aForceDisable; |
989 | | } |
990 | 0 | bool IsApzForceDisabled() const { |
991 | 0 | return mForceDisableApz; |
992 | 0 | } |
993 | | |
994 | | // For more details about the concept of a disregarded direction, refer to the |
995 | | // code which defines mDisregardedDirection. |
996 | 0 | Maybe<ScrollDirection> GetDisregardedDirection() const { |
997 | 0 | return mDisregardedDirection; |
998 | 0 | } |
999 | | void |
1000 | 0 | SetDisregardedDirection(const Maybe<ScrollDirection>& aValue) { |
1001 | 0 | mDisregardedDirection = aValue; |
1002 | 0 | } |
1003 | | |
1004 | 0 | void SetOverscrollBehavior(const OverscrollBehaviorInfo& aOverscrollBehavior) { |
1005 | 0 | mOverscrollBehavior = aOverscrollBehavior; |
1006 | 0 | } |
1007 | | const OverscrollBehaviorInfo& GetOverscrollBehavior() const { |
1008 | | return mOverscrollBehavior; |
1009 | | } |
1010 | | |
1011 | | private: |
1012 | | FrameMetrics mMetrics; |
1013 | | |
1014 | | // Information used to determine where to snap to for a given scroll. |
1015 | | ScrollSnapInfo mSnapInfo; |
1016 | | |
1017 | | // The ViewID of the scrollable frame to which overscroll should be handed off. |
1018 | | ViewID mScrollParentId; |
1019 | | |
1020 | | // The background color to use when overscrolling. |
1021 | | gfx::Color mBackgroundColor; |
1022 | | |
1023 | | // A description of the content element corresponding to this frame. |
1024 | | // This is empty unless this is a scrollable layer and the |
1025 | | // apz.printtree pref is turned on. |
1026 | | nsCString mContentDescription; |
1027 | | |
1028 | | // The value of GetLineScrollAmount(), for scroll frames. |
1029 | | LayoutDeviceIntSize mLineScrollAmount; |
1030 | | |
1031 | | // The value of GetPageScrollAmount(), for scroll frames. |
1032 | | LayoutDeviceIntSize mPageScrollAmount; |
1033 | | |
1034 | | // A clip to apply when compositing the layer bearing this ScrollMetadata, |
1035 | | // after applying any transform arising from scrolling this scroll frame. |
1036 | | // Note that, unlike most other fields of ScrollMetadata, this is allowed |
1037 | | // to differ between different layers scrolled by the same scroll frame. |
1038 | | // TODO: Group the fields of ScrollMetadata into sub-structures to separate |
1039 | | // fields with this property better. |
1040 | | Maybe<LayerClip> mScrollClip; |
1041 | | |
1042 | | // Whether or not this frame is for an element marked 'scrollgrab'. |
1043 | | bool mHasScrollgrab:1; |
1044 | | |
1045 | | // Whether these framemetrics are for the root scroll frame (root element if |
1046 | | // we don't have a root scroll frame) for its layers id. |
1047 | | bool mIsLayersIdRoot:1; |
1048 | | |
1049 | | // The AutoDirRootContent is the <body> element in an HTML document, or the |
1050 | | // root scrollframe if there is no body. This member variable indicates |
1051 | | // whether this element's content in the horizontal direction starts from |
1052 | | // right to left (e.g. it's true either if "writing-mode: vertical-rl", or |
1053 | | // "writing-mode: horizontal-tb; direction: rtl" in CSS). |
1054 | | // When we do auto-dir scrolling (@see mozilla::WheelDeltaAdjustmentStrategy |
1055 | | // or refer to bug 1358017 for details), setting a pref can make the code use |
1056 | | // the writing mode of this root element instead of the target scrollframe, |
1057 | | // and so we need to know if the writing mode is RTL or not. |
1058 | | bool mIsAutoDirRootContentRTL:1; |
1059 | | |
1060 | | // True if scrolling using containers, false otherwise. This can be removed |
1061 | | // when containerful scrolling is eliminated. |
1062 | | bool mUsesContainerScrolling:1; |
1063 | | |
1064 | | // Whether or not the compositor should actually do APZ-scrolling on this |
1065 | | // scrollframe. |
1066 | | bool mForceDisableApz:1; |
1067 | | |
1068 | | // The disregarded direction means the direction which is disregarded anyway, |
1069 | | // even if the scroll frame overflows in that direction and the direction is |
1070 | | // specified as scrollable. This could happen in some scenarios, for instance, |
1071 | | // a single-line text control frame should disregard wheel scroll in |
1072 | | // its block-flow direction even if it overflows in that direction. |
1073 | | Maybe<ScrollDirection> mDisregardedDirection; |
1074 | | |
1075 | | // The overscroll behavior for this scroll frame. |
1076 | | OverscrollBehaviorInfo mOverscrollBehavior; |
1077 | | |
1078 | | // WARNING!!!! |
1079 | | // |
1080 | | // When adding new fields to ScrollMetadata, the following places should be |
1081 | | // updated to include them (as needed): |
1082 | | // 1. ScrollMetadata::operator == |
1083 | | // 2. AsyncPanZoomController::NotifyLayersUpdated |
1084 | | // 3. The ParamTraits specialization in GfxMessageUtils.h and/or |
1085 | | // LayersMessageUtils.h |
1086 | | // |
1087 | | // Please add new fields above this comment. |
1088 | | }; |
1089 | | |
1090 | | /** |
1091 | | * This class allows us to uniquely identify a scrollable layer. The |
1092 | | * mLayersId identifies the layer tree (corresponding to a child process |
1093 | | * and/or tab) that the scrollable layer belongs to. The mPresShellId |
1094 | | * is a temporal identifier (corresponding to the document loaded that |
1095 | | * contains the scrollable layer, which may change over time). The |
1096 | | * mScrollId corresponds to the actual frame that is scrollable. |
1097 | | */ |
1098 | | struct ScrollableLayerGuid { |
1099 | | LayersId mLayersId; |
1100 | | uint32_t mPresShellId; |
1101 | | FrameMetrics::ViewID mScrollId; |
1102 | | |
1103 | | ScrollableLayerGuid() |
1104 | | : mLayersId{0} |
1105 | | , mPresShellId(0) |
1106 | | , mScrollId(0) |
1107 | | { |
1108 | | } |
1109 | | |
1110 | | ScrollableLayerGuid(LayersId aLayersId, uint32_t aPresShellId, |
1111 | | FrameMetrics::ViewID aScrollId) |
1112 | | : mLayersId(aLayersId) |
1113 | | , mPresShellId(aPresShellId) |
1114 | | , mScrollId(aScrollId) |
1115 | 0 | { |
1116 | 0 | } |
1117 | | |
1118 | | ScrollableLayerGuid(LayersId aLayersId, const FrameMetrics& aMetrics) |
1119 | | : mLayersId(aLayersId) |
1120 | | , mPresShellId(aMetrics.GetPresShellId()) |
1121 | | , mScrollId(aMetrics.GetScrollId()) |
1122 | 0 | { |
1123 | 0 | } |
1124 | | |
1125 | | ScrollableLayerGuid(const ScrollableLayerGuid& other) |
1126 | | : mLayersId(other.mLayersId) |
1127 | | , mPresShellId(other.mPresShellId) |
1128 | | , mScrollId(other.mScrollId) |
1129 | 0 | { |
1130 | 0 | } |
1131 | | |
1132 | | ~ScrollableLayerGuid() |
1133 | | { |
1134 | | } |
1135 | | |
1136 | | bool operator==(const ScrollableLayerGuid& other) const |
1137 | 0 | { |
1138 | 0 | return mLayersId == other.mLayersId |
1139 | 0 | && mPresShellId == other.mPresShellId |
1140 | 0 | && mScrollId == other.mScrollId; |
1141 | 0 | } |
1142 | | |
1143 | | bool operator!=(const ScrollableLayerGuid& other) const |
1144 | | { |
1145 | | return !(*this == other); |
1146 | | } |
1147 | | |
1148 | | bool operator<(const ScrollableLayerGuid& other) const |
1149 | | { |
1150 | | if (mLayersId < other.mLayersId) { |
1151 | | return true; |
1152 | | } |
1153 | | if (mLayersId == other.mLayersId) { |
1154 | | if (mPresShellId < other.mPresShellId) { |
1155 | | return true; |
1156 | | } |
1157 | | if (mPresShellId == other.mPresShellId) { |
1158 | | return mScrollId < other.mScrollId; |
1159 | | } |
1160 | | } |
1161 | | return false; |
1162 | | } |
1163 | | |
1164 | | // Helper structs to use as hash/equality functions in std::unordered_map. e.g. |
1165 | | // std::unordered_map<ScrollableLayerGuid, |
1166 | | // ValueType, |
1167 | | // ScrollableLayerGuid::HashFn> myMap; |
1168 | | // std::unordered_map<ScrollableLayerGuid, |
1169 | | // ValueType, |
1170 | | // ScrollableLayerGuid::HashIgnoringPresShellFn, |
1171 | | // ScrollableLayerGuid::EqualIgnoringPresShellFn> myMap; |
1172 | | |
1173 | | struct HashFn |
1174 | | { |
1175 | | std::size_t operator()(const ScrollableLayerGuid& aGuid) const |
1176 | 0 | { |
1177 | 0 | return HashGeneric(uint64_t(aGuid.mLayersId), |
1178 | 0 | aGuid.mPresShellId, |
1179 | 0 | aGuid.mScrollId); |
1180 | 0 | } |
1181 | | }; |
1182 | | |
1183 | | struct HashIgnoringPresShellFn |
1184 | | { |
1185 | | std::size_t operator()(const ScrollableLayerGuid& aGuid) const |
1186 | 0 | { |
1187 | 0 | return HashGeneric(uint64_t(aGuid.mLayersId), |
1188 | 0 | aGuid.mScrollId); |
1189 | 0 | } |
1190 | | }; |
1191 | | |
1192 | | struct EqualIgnoringPresShellFn |
1193 | | { |
1194 | | bool operator()(const ScrollableLayerGuid& lhs, const ScrollableLayerGuid& rhs) const |
1195 | 0 | { |
1196 | 0 | return lhs.mLayersId == rhs.mLayersId |
1197 | 0 | && lhs.mScrollId == rhs.mScrollId; |
1198 | 0 | } |
1199 | | }; |
1200 | | }; |
1201 | | |
1202 | | template <int LogLevel> |
1203 | 0 | gfx::Log<LogLevel>& operator<<(gfx::Log<LogLevel>& log, const ScrollableLayerGuid& aGuid) { |
1204 | 0 | return log << '(' << uint64_t(aGuid.mLayersId) << ',' << aGuid.mPresShellId << ',' << aGuid.mScrollId << ')'; |
1205 | 0 | } |
1206 | | |
1207 | | struct ZoomConstraints { |
1208 | | bool mAllowZoom; |
1209 | | bool mAllowDoubleTapZoom; |
1210 | | CSSToParentLayerScale mMinZoom; |
1211 | | CSSToParentLayerScale mMaxZoom; |
1212 | | |
1213 | | ZoomConstraints() |
1214 | | : mAllowZoom(true) |
1215 | | , mAllowDoubleTapZoom(true) |
1216 | | { |
1217 | | MOZ_COUNT_CTOR(ZoomConstraints); |
1218 | | } |
1219 | | |
1220 | | ZoomConstraints(bool aAllowZoom, |
1221 | | bool aAllowDoubleTapZoom, |
1222 | | const CSSToParentLayerScale& aMinZoom, |
1223 | | const CSSToParentLayerScale& aMaxZoom) |
1224 | | : mAllowZoom(aAllowZoom) |
1225 | | , mAllowDoubleTapZoom(aAllowDoubleTapZoom) |
1226 | | , mMinZoom(aMinZoom) |
1227 | | , mMaxZoom(aMaxZoom) |
1228 | 0 | { |
1229 | 0 | MOZ_COUNT_CTOR(ZoomConstraints); |
1230 | 0 | } |
1231 | | |
1232 | | ZoomConstraints(const ZoomConstraints& other) |
1233 | | : mAllowZoom(other.mAllowZoom) |
1234 | | , mAllowDoubleTapZoom(other.mAllowDoubleTapZoom) |
1235 | | , mMinZoom(other.mMinZoom) |
1236 | | , mMaxZoom(other.mMaxZoom) |
1237 | | { |
1238 | | MOZ_COUNT_CTOR(ZoomConstraints); |
1239 | | } |
1240 | | |
1241 | | ~ZoomConstraints() |
1242 | | { |
1243 | | MOZ_COUNT_DTOR(ZoomConstraints); |
1244 | | } |
1245 | | |
1246 | | bool operator==(const ZoomConstraints& other) const |
1247 | | { |
1248 | | return mAllowZoom == other.mAllowZoom |
1249 | | && mAllowDoubleTapZoom == other.mAllowDoubleTapZoom |
1250 | | && mMinZoom == other.mMinZoom |
1251 | | && mMaxZoom == other.mMaxZoom; |
1252 | | } |
1253 | | |
1254 | | bool operator!=(const ZoomConstraints& other) const |
1255 | | { |
1256 | | return !(*this == other); |
1257 | | } |
1258 | | }; |
1259 | | |
1260 | | |
1261 | | typedef Maybe<ZoomConstraints> MaybeZoomConstraints; |
1262 | | |
1263 | | typedef std::map<FrameMetrics::ViewID,ScrollUpdateInfo> ScrollUpdatesMap; |
1264 | | |
1265 | | } // namespace layers |
1266 | | } // namespace mozilla |
1267 | | |
1268 | | #endif /* GFX_FRAMEMETRICS_H */ |