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