Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/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
0
  {
100
0
  }
101
102
  // Default copy ctor and operator= are fine
103
104
  bool operator==(const FrameMetrics& aOther) const
105
0
  {
106
0
    // 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
0
           // 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
0
           mDoSmoothScroll == aOther.mDoSmoothScroll &&
128
0
           mUseDisplayPortMargins == aOther.mUseDisplayPortMargins &&
129
0
           mIsScrollInfoLayer == aOther.mIsScrollInfoLayer;
130
0
  }
131
132
  bool operator!=(const FrameMetrics& aOther) const
133
0
  {
134
0
    return !operator==(aOther);
135
0
  }
136
137
  bool IsScrollable() const
138
0
  {
139
0
    return mScrollId != NULL_SCROLL_ID;
140
0
  }
141
142
  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
    return mZoom * ParentLayerToLayerScale(1.0f) / mExtraResolution;
152
  }
153
154
  CSSToLayerScale2D LayersPixelsPerCSSPixel() const
155
  {
156
    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
0
  {
162
0
    // The async portion of the zoom should be the same along the x and y
163
0
    // axes.
164
0
    return (mZoom / LayersPixelsPerCSSPixel()).ToScaleFactor();
165
0
  }
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
0
  {
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
0
    }
182
0
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
0
    }
188
0
189
0
    return scrollableRect;
190
0
  }
191
192
  CSSSize CalculateCompositedSizeInCssPixels() const
193
  {
194
    if (GetZoom() == CSSToParentLayerScale2D(0, 0)) {
195
      return CSSSize();  // avoid division by zero
196
    }
197
    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
  CSSRect CalculateCompositionBoundsInCssPixelsOfSurroundingContent() const
211
  {
212
    if (GetZoom() == CSSToParentLayerScale2D(0, 0)) {
213
      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
    return mCompositionBounds / GetZoom() * CSSToCSSScale{mPresShellResolution};
219
  }
220
221
  CSSSize CalculateBoundedCompositedSizeInCssPixels() const
222
  {
223
    CSSSize size = CalculateCompositedSizeInCssPixels();
224
    size.width = std::min(size.width, mRootCompositionSize.width);
225
    size.height = std::min(size.height, mRootCompositionSize.height);
226
    return size;
227
  }
228
229
  CSSRect CalculateScrollRange() const
230
  {
231
    CSSSize scrollPortSize = CalculateCompositedSizeInCssPixels();
232
    CSSRect scrollRange = mScrollableRect;
233
    scrollRange.SetWidth(std::max(scrollRange.Width() - scrollPortSize.width, 0.0f));
234
    scrollRange.SetHeight(std::max(scrollRange.Height() - scrollPortSize.height, 0.0f));
235
    return scrollRange;
236
  }
237
238
  void ScrollBy(const CSSPoint& aPoint)
239
  {
240
    mScrollOffset += aPoint;
241
  }
242
243
  void ZoomBy(float aScale)
244
  {
245
    ZoomBy(gfxSize(aScale, aScale));
246
  }
247
248
  void ZoomBy(const gfxSize& aScale)
249
  {
250
    mZoom.xScale *= aScale.width;
251
    mZoom.yScale *= aScale.height;
252
  }
253
254
  void CopyScrollInfoFrom(const FrameMetrics& aOther)
255
  {
256
    mScrollOffset = aOther.mScrollOffset;
257
    mScrollGeneration = aOther.mScrollGeneration;
258
  }
259
260
  void CopySmoothScrollInfoFrom(const FrameMetrics& aOther)
261
  {
262
    mSmoothScrollOffset = aOther.mSmoothScrollOffset;
263
    mScrollGeneration = aOther.mScrollGeneration;
264
    mDoSmoothScroll = aOther.mDoSmoothScroll;
265
  }
266
267
  void UpdatePendingScrollInfo(const ScrollUpdateInfo& aInfo)
268
0
  {
269
0
    mScrollOffset = aInfo.mScrollOffset;
270
0
    mScrollGeneration = aInfo.mScrollGeneration;
271
0
    mScrollUpdateType = ePending;
272
0
  }
273
274
  void SetRepaintDrivenByUserAction(bool aUserAction)
275
  {
276
    mScrollUpdateType = aUserAction ? eUserAction : eNone;
277
  }
278
279
public:
280
  void SetPresShellResolution(float aPresShellResolution)
281
  {
282
    mPresShellResolution = aPresShellResolution;
283
  }
284
285
  float GetPresShellResolution() const
286
0
  {
287
0
    return mPresShellResolution;
288
0
  }
289
290
  void SetCompositionBounds(const ParentLayerRect& aCompositionBounds)
291
  {
292
    mCompositionBounds = aCompositionBounds;
293
  }
294
295
  const ParentLayerRect& GetCompositionBounds() const
296
0
  {
297
0
    return mCompositionBounds;
298
0
  }
299
300
  void SetDisplayPort(const CSSRect& aDisplayPort)
301
0
  {
302
0
    mDisplayPort = aDisplayPort;
303
0
  }
304
305
  const CSSRect& GetDisplayPort() const
306
0
  {
307
0
    return mDisplayPort;
308
0
  }
309
310
  void SetCriticalDisplayPort(const CSSRect& aCriticalDisplayPort)
311
0
  {
312
0
    mCriticalDisplayPort = aCriticalDisplayPort;
313
0
  }
314
315
  const CSSRect& GetCriticalDisplayPort() const
316
0
  {
317
0
    return mCriticalDisplayPort;
318
0
  }
319
320
  void SetCumulativeResolution(const LayoutDeviceToLayerScale2D& aCumulativeResolution)
321
  {
322
    mCumulativeResolution = aCumulativeResolution;
323
  }
324
325
  const LayoutDeviceToLayerScale2D& GetCumulativeResolution() const
326
0
  {
327
0
    return mCumulativeResolution;
328
0
  }
329
330
  void SetDevPixelsPerCSSPixel(const CSSToLayoutDeviceScale& aDevPixelsPerCSSPixel)
331
  {
332
    mDevPixelsPerCSSPixel = aDevPixelsPerCSSPixel;
333
  }
334
335
  const CSSToLayoutDeviceScale& GetDevPixelsPerCSSPixel() const
336
0
  {
337
0
    return mDevPixelsPerCSSPixel;
338
0
  }
339
340
  void SetIsRootContent(bool aIsRootContent)
341
0
  {
342
0
    mIsRootContent = aIsRootContent;
343
0
  }
344
345
  bool IsRootContent() const
346
0
  {
347
0
    return mIsRootContent;
348
0
  }
349
350
  void SetScrollOffset(const CSSPoint& aScrollOffset)
351
  {
352
    mScrollOffset = aScrollOffset;
353
  }
354
355
  // Set scroll offset, first clamping to the scroll range.
356
  void ClampAndSetScrollOffset(const CSSPoint& aScrollOffset)
357
  {
358
    SetScrollOffset(CalculateScrollRange().ClampPoint(aScrollOffset));
359
  }
360
361
  const CSSPoint& GetScrollOffset() const
362
0
  {
363
0
    return mScrollOffset;
364
0
  }
365
366
  void SetSmoothScrollOffset(const CSSPoint& aSmoothScrollDestination)
367
0
  {
368
0
    mSmoothScrollOffset = aSmoothScrollDestination;
369
0
  }
370
371
  const CSSPoint& GetSmoothScrollOffset() const
372
0
  {
373
0
    return mSmoothScrollOffset;
374
0
  }
375
376
  void SetZoom(const CSSToParentLayerScale2D& aZoom)
377
  {
378
    mZoom = aZoom;
379
  }
380
381
  const CSSToParentLayerScale2D& GetZoom() const
382
  {
383
    return mZoom;
384
  }
385
386
  void SetScrollOffsetUpdated(uint32_t aScrollGeneration)
387
0
  {
388
0
    mScrollUpdateType = eMainThread;
389
0
    mScrollGeneration = aScrollGeneration;
390
0
  }
391
392
  void SetScrollOffsetRestored(uint32_t aScrollGeneration)
393
0
  {
394
0
    mScrollUpdateType = eRestore;
395
0
    mScrollGeneration = aScrollGeneration;
396
0
  }
397
398
  void SetSmoothScrollOffsetUpdated(int32_t aScrollGeneration)
399
0
  {
400
0
    mDoSmoothScroll = true;
401
0
    mScrollGeneration = aScrollGeneration;
402
0
  }
403
404
  ScrollOffsetUpdateType GetScrollUpdateType() const
405
0
  {
406
0
    return mScrollUpdateType;
407
0
  }
408
409
  bool GetScrollOffsetUpdated() const
410
  {
411
    return mScrollUpdateType != eNone;
412
  }
413
414
  bool GetDoSmoothScroll() const
415
0
  {
416
0
    return mDoSmoothScroll;
417
0
  }
418
419
  uint32_t GetScrollGeneration() const
420
0
  {
421
0
    return mScrollGeneration;
422
0
  }
423
424
  ViewID GetScrollId() const
425
0
  {
426
0
    return mScrollId;
427
0
  }
428
429
  void SetScrollId(ViewID scrollId)
430
0
  {
431
0
    mScrollId = scrollId;
432
0
  }
433
434
  void SetRootCompositionSize(const CSSSize& aRootCompositionSize)
435
  {
436
    mRootCompositionSize = aRootCompositionSize;
437
  }
438
439
  const CSSSize& GetRootCompositionSize() const
440
0
  {
441
0
    return mRootCompositionSize;
442
0
  }
443
444
  void SetDisplayPortMargins(const ScreenMargin& aDisplayPortMargins)
445
  {
446
    mDisplayPortMargins = aDisplayPortMargins;
447
  }
448
449
  const ScreenMargin& GetDisplayPortMargins() const
450
0
  {
451
0
    return mDisplayPortMargins;
452
0
  }
453
454
  void SetUseDisplayPortMargins(bool aValue)
455
0
  {
456
0
    mUseDisplayPortMargins = aValue;
457
0
  }
458
459
  bool GetUseDisplayPortMargins() const
460
0
  {
461
0
    return mUseDisplayPortMargins;
462
0
  }
463
464
  uint32_t GetPresShellId() const
465
0
  {
466
0
    return mPresShellId;
467
0
  }
468
469
  void SetPresShellId(uint32_t aPresShellId)
470
0
  {
471
0
    mPresShellId = aPresShellId;
472
0
  }
473
474
  void SetViewport(const CSSRect& aViewport)
475
  {
476
    mViewport = aViewport;
477
  }
478
479
  const CSSRect& GetViewport() const
480
0
  {
481
0
    return mViewport;
482
0
  }
483
484
  CSSRect GetVisualViewport() const
485
  {
486
    return CSSRect(mScrollOffset, CalculateCompositedSizeInCssPixels());
487
  }
488
489
  void SetExtraResolution(const ScreenToLayerScale2D& aExtraResolution)
490
0
  {
491
0
    mExtraResolution = aExtraResolution;
492
0
  }
493
494
  const ScreenToLayerScale2D& GetExtraResolution() const
495
0
  {
496
0
    return mExtraResolution;
497
0
  }
498
499
  const CSSRect& GetScrollableRect() const
500
0
  {
501
0
    return mScrollableRect;
502
0
  }
503
504
  void SetScrollableRect(const CSSRect& aScrollableRect)
505
  {
506
    mScrollableRect = aScrollableRect;
507
  }
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
  bool IsHorizontalContentRightToLeft() const {
517
    return mScrollableRect.x < 0;
518
  }
519
520
  void SetPaintRequestTime(const TimeStamp& aTime) {
521
    mPaintRequestTime = aTime;
522
  }
523
  const TimeStamp& GetPaintRequestTime() const {
524
    return mPaintRequestTime;
525
  }
526
527
0
  void SetIsScrollInfoLayer(bool aIsScrollInfoLayer) {
528
0
    mIsScrollInfoLayer = aIsScrollInfoLayer;
529
0
  }
530
  bool IsScrollInfoLayer() const {
531
    return mIsScrollInfoLayer;
532
  }
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
0
  void SetDoSmoothScroll(bool aValue) {
719
0
    mDoSmoothScroll = aValue;
720
0
  }
721
};
722
723
struct ScrollSnapInfo {
724
  ScrollSnapInfo()
725
    : mScrollSnapTypeX(NS_STYLE_SCROLL_SNAP_TYPE_NONE)
726
    , mScrollSnapTypeY(NS_STYLE_SCROLL_SNAP_TYPE_NONE)
727
0
  {}
728
729
  bool operator==(const ScrollSnapInfo& aOther) const
730
0
  {
731
0
    return mScrollSnapTypeX == aOther.mScrollSnapTypeX &&
732
0
           mScrollSnapTypeY == aOther.mScrollSnapTypeY &&
733
0
           mScrollSnapIntervalX == aOther.mScrollSnapIntervalX &&
734
0
           mScrollSnapIntervalY == aOther.mScrollSnapIntervalY &&
735
0
           mScrollSnapDestination == aOther.mScrollSnapDestination &&
736
0
           mScrollSnapCoordinates == aOther.mScrollSnapCoordinates;
737
0
  }
738
739
  bool HasScrollSnapping() const
740
0
  {
741
0
    return mScrollSnapTypeY != NS_STYLE_SCROLL_SNAP_TYPE_NONE ||
742
0
           mScrollSnapTypeX != NS_STYLE_SCROLL_SNAP_TYPE_NONE;
743
0
  }
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
0
  {}
775
776
  // Construct from StyleOverscrollBehavior values.
777
  static OverscrollBehaviorInfo FromStyleConstants(StyleOverscrollBehavior aBehaviorX,
778
                                                   StyleOverscrollBehavior aBehaviorY);
779
780
0
  bool operator==(const OverscrollBehaviorInfo& aOther) const {
781
0
    return mBehaviorX == aOther.mBehaviorX &&
782
0
           mBehaviorY == aOther.mBehaviorY;
783
0
  }
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
0
  {}
801
802
  explicit LayerClip(const ParentLayerIntRect& aClipRect)
803
    : mClipRect(aClipRect)
804
    , mMaskLayerIndex()
805
0
  {}
806
807
  bool operator==(const LayerClip& aOther) const
808
0
  {
809
0
    return mClipRect == aOther.mClipRect &&
810
0
           mMaskLayerIndex == aOther.mMaskLayerIndex;
811
0
  }
812
813
0
  void SetClipRect(const ParentLayerIntRect& aClipRect) {
814
0
    mClipRect = aClipRect;
815
0
  }
816
0
  const ParentLayerIntRect& GetClipRect() const {
817
0
    return mClipRect;
818
0
  }
819
820
0
  void SetMaskLayerIndex(const Maybe<size_t>& aIndex) {
821
0
    mMaskLayerIndex = aIndex;
822
0
  }
823
0
  const Maybe<size_t>& GetMaskLayerIndex() const {
824
0
    return mMaskLayerIndex;
825
0
  }
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
0
  {}
867
868
  bool operator==(const ScrollMetadata& aOther) const
869
0
  {
870
0
    return mMetrics == aOther.mMetrics &&
871
0
           mSnapInfo == aOther.mSnapInfo &&
872
0
           mScrollParentId == aOther.mScrollParentId &&
873
0
           mBackgroundColor == aOther.mBackgroundColor &&
874
0
           // don't compare mContentDescription
875
0
           mLineScrollAmount == aOther.mLineScrollAmount &&
876
0
           mPageScrollAmount == aOther.mPageScrollAmount &&
877
0
           mScrollClip == aOther.mScrollClip &&
878
0
           mHasScrollgrab == aOther.mHasScrollgrab &&
879
0
           mIsLayersIdRoot == aOther.mIsLayersIdRoot &&
880
0
           mIsAutoDirRootContentRTL == aOther.mIsAutoDirRootContentRTL &&
881
0
           mUsesContainerScrolling == aOther.mUsesContainerScrolling &&
882
0
           mForceDisableApz == aOther.mForceDisableApz &&
883
0
           mDisregardedDirection == aOther.mDisregardedDirection &&
884
0
           mOverscrollBehavior == aOther.mOverscrollBehavior;
885
0
  }
886
887
  bool operator!=(const ScrollMetadata& aOther) const
888
0
  {
889
0
    return !operator==(aOther);
890
0
  }
891
892
  bool IsDefault() const
893
0
  {
894
0
    ScrollMetadata def;
895
0
896
0
    def.mMetrics.SetPresShellId(mMetrics.GetPresShellId());
897
0
    return (def == *this);
898
0
  }
899
900
0
  FrameMetrics& GetMetrics() { return mMetrics; }
901
0
  const FrameMetrics& GetMetrics() const { return mMetrics; }
902
903
  void SetSnapInfo(ScrollSnapInfo&& aSnapInfo) {
904
    mSnapInfo = std::move(aSnapInfo);
905
  }
906
  const ScrollSnapInfo& GetSnapInfo() const { return mSnapInfo; }
907
908
0
  ViewID GetScrollParentId() const {
909
0
    return mScrollParentId;
910
0
  }
911
912
  void SetScrollParentId(ViewID aParentId) {
913
    mScrollParentId = aParentId;
914
  }
915
0
  const gfx::Color& GetBackgroundColor() const {
916
0
    return mBackgroundColor;
917
0
  }
918
0
  void SetBackgroundColor(const gfx::Color& aBackgroundColor) {
919
0
    mBackgroundColor = aBackgroundColor;
920
0
  }
921
0
  const nsCString& GetContentDescription() const {
922
0
    return mContentDescription;
923
0
  }
924
0
  void SetContentDescription(const nsCString& aContentDescription) {
925
0
    mContentDescription = aContentDescription;
926
0
  }
927
  const LayoutDeviceIntSize& GetLineScrollAmount() const {
928
    return mLineScrollAmount;
929
  }
930
  void SetLineScrollAmount(const LayoutDeviceIntSize& size) {
931
    mLineScrollAmount = size;
932
  }
933
  const LayoutDeviceIntSize& GetPageScrollAmount() const {
934
    return mPageScrollAmount;
935
  }
936
  void SetPageScrollAmount(const LayoutDeviceIntSize& size) {
937
    mPageScrollAmount = size;
938
  }
939
940
  void SetScrollClip(const Maybe<LayerClip>& aScrollClip) {
941
    mScrollClip = aScrollClip;
942
  }
943
0
  const Maybe<LayerClip>& GetScrollClip() const {
944
0
    return mScrollClip;
945
0
  }
946
0
  bool HasScrollClip() const {
947
0
    return mScrollClip.isSome();
948
0
  }
949
0
  const LayerClip& ScrollClip() const {
950
0
    return mScrollClip.ref();
951
0
  }
952
0
  LayerClip& ScrollClip() {
953
0
    return mScrollClip.ref();
954
0
  }
955
956
0
  bool HasMaskLayer() const {
957
0
    return HasScrollClip() && ScrollClip().GetMaskLayerIndex();
958
0
  }
959
0
  Maybe<ParentLayerIntRect> GetClipRect() const {
960
0
    return mScrollClip.isSome() ? Some(mScrollClip->GetClipRect()) : Nothing();
961
0
  }
962
963
0
  void SetHasScrollgrab(bool aHasScrollgrab) {
964
0
    mHasScrollgrab = aHasScrollgrab;
965
0
  }
966
  bool GetHasScrollgrab() const {
967
    return mHasScrollgrab;
968
  }
969
0
  void SetIsLayersIdRoot(bool aValue) {
970
0
    mIsLayersIdRoot = aValue;
971
0
  }
972
  bool IsLayersIdRoot() const {
973
    return mIsLayersIdRoot;
974
  }
975
0
  void SetIsAutoDirRootContentRTL(bool aValue) {
976
0
    mIsAutoDirRootContentRTL = aValue;
977
0
  }
978
  bool IsAutoDirRootContentRTL() const {
979
    return mIsAutoDirRootContentRTL;
980
  }
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
  bool UsesContainerScrolling() const {
985
    return mUsesContainerScrolling;
986
  }
987
0
  void SetForceDisableApz(bool aForceDisable) {
988
0
    mForceDisableApz = aForceDisable;
989
0
  }
990
  bool IsApzForceDisabled() const {
991
    return mForceDisableApz;
992
  }
993
994
  // For more details about the concept of a disregarded direction, refer to the
995
  // code which defines mDisregardedDirection.
996
  Maybe<ScrollDirection> GetDisregardedDirection() const {
997
    return mDisregardedDirection;
998
  }
999
  void
1000
  SetDisregardedDirection(const Maybe<ScrollDirection>& aValue) {
1001
    mDisregardedDirection = aValue;
1002
  }
1003
1004
  void SetOverscrollBehavior(const OverscrollBehaviorInfo& aOverscrollBehavior) {
1005
    mOverscrollBehavior = aOverscrollBehavior;
1006
  }
1007
0
  const OverscrollBehaviorInfo& GetOverscrollBehavior() const {
1008
0
    return mOverscrollBehavior;
1009
0
  }
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
3
  {
1108
3
  }
1109
1110
  ScrollableLayerGuid(LayersId aLayersId, uint32_t aPresShellId,
1111
                      FrameMetrics::ViewID aScrollId)
1112
    : mLayersId(aLayersId)
1113
    , mPresShellId(aPresShellId)
1114
    , mScrollId(aScrollId)
1115
  {
1116
  }
1117
1118
  ScrollableLayerGuid(LayersId aLayersId, const FrameMetrics& aMetrics)
1119
    : mLayersId(aLayersId)
1120
    , mPresShellId(aMetrics.GetPresShellId())
1121
    , mScrollId(aMetrics.GetScrollId())
1122
  {
1123
  }
1124
1125
  ScrollableLayerGuid(const ScrollableLayerGuid& other)
1126
    : mLayersId(other.mLayersId)
1127
    , mPresShellId(other.mPresShellId)
1128
    , mScrollId(other.mScrollId)
1129
  {
1130
  }
1131
1132
  ~ScrollableLayerGuid()
1133
0
  {
1134
0
  }
1135
1136
  bool operator==(const ScrollableLayerGuid& other) const
1137
  {
1138
    return mLayersId == other.mLayersId
1139
        && mPresShellId == other.mPresShellId
1140
        && mScrollId == other.mScrollId;
1141
  }
1142
1143
  bool operator!=(const ScrollableLayerGuid& other) const
1144
0
  {
1145
0
    return !(*this == other);
1146
0
  }
1147
1148
  bool operator<(const ScrollableLayerGuid& other) const
1149
0
  {
1150
0
    if (mLayersId < other.mLayersId) {
1151
0
      return true;
1152
0
    }
1153
0
    if (mLayersId == other.mLayersId) {
1154
0
      if (mPresShellId < other.mPresShellId) {
1155
0
        return true;
1156
0
      }
1157
0
      if (mPresShellId == other.mPresShellId) {
1158
0
        return mScrollId < other.mScrollId;
1159
0
      }
1160
0
    }
1161
0
    return false;
1162
0
  }
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
    {
1177
      return HashGeneric(uint64_t(aGuid.mLayersId),
1178
                         aGuid.mPresShellId,
1179
                         aGuid.mScrollId);
1180
    }
1181
  };
1182
1183
  struct HashIgnoringPresShellFn
1184
  {
1185
    std::size_t operator()(const ScrollableLayerGuid& aGuid) const
1186
    {
1187
      return HashGeneric(uint64_t(aGuid.mLayersId),
1188
                         aGuid.mScrollId);
1189
    }
1190
  };
1191
1192
  struct EqualIgnoringPresShellFn
1193
  {
1194
    bool operator()(const ScrollableLayerGuid& lhs, const ScrollableLayerGuid& rhs) const
1195
    {
1196
      return lhs.mLayersId == rhs.mLayersId
1197
          && lhs.mScrollId == rhs.mScrollId;
1198
    }
1199
  };
1200
};
1201
1202
template <int LogLevel>
1203
gfx::Log<LogLevel>& operator<<(gfx::Log<LogLevel>& log, const ScrollableLayerGuid& aGuid) {
1204
  return log << '(' << uint64_t(aGuid.mLayersId) << ',' << aGuid.mPresShellId << ',' << aGuid.mScrollId << ')';
1205
}
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
0
  {
1217
0
    MOZ_COUNT_CTOR(ZoomConstraints);
1218
0
  }
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
  {
1229
    MOZ_COUNT_CTOR(ZoomConstraints);
1230
  }
1231
1232
  ZoomConstraints(const ZoomConstraints& other)
1233
    : mAllowZoom(other.mAllowZoom)
1234
    , mAllowDoubleTapZoom(other.mAllowDoubleTapZoom)
1235
    , mMinZoom(other.mMinZoom)
1236
    , mMaxZoom(other.mMaxZoom)
1237
0
  {
1238
0
    MOZ_COUNT_CTOR(ZoomConstraints);
1239
0
  }
1240
1241
  ~ZoomConstraints()
1242
0
  {
1243
0
    MOZ_COUNT_DTOR(ZoomConstraints);
1244
0
  }
1245
1246
  bool operator==(const ZoomConstraints& other) const
1247
0
  {
1248
0
    return mAllowZoom == other.mAllowZoom
1249
0
        && mAllowDoubleTapZoom == other.mAllowDoubleTapZoom
1250
0
        && mMinZoom == other.mMinZoom
1251
0
        && mMaxZoom == other.mMaxZoom;
1252
0
  }
1253
1254
  bool operator!=(const ZoomConstraints& other) const
1255
0
  {
1256
0
    return !(*this == other);
1257
0
  }
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 */