1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/FrameMetrics.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,587 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef GFX_FRAMEMETRICS_H 1.10 +#define GFX_FRAMEMETRICS_H 1.11 + 1.12 +#include <stdint.h> // for uint32_t, uint64_t 1.13 +#include <string> // for std::string 1.14 +#include "Units.h" // for CSSRect, CSSPixel, etc 1.15 +#include "mozilla/gfx/BasePoint.h" // for BasePoint 1.16 +#include "mozilla/gfx/Rect.h" // for RoundedIn 1.17 +#include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor 1.18 +#include "mozilla/gfx/Logging.h" // for Log 1.19 + 1.20 +namespace IPC { 1.21 +template <typename T> struct ParamTraits; 1.22 +} // namespace IPC 1.23 + 1.24 +namespace mozilla { 1.25 + 1.26 +// The layer coordinates of the parent layer. 1.27 +// This can be arrived at in two ways: 1.28 +// - Start with the CSS coordinates of the parent layer (note: NOT the 1.29 +// CSS coordinates of the current layer, that will give you the wrong 1.30 +// answer), multiply by the device scale and the resolutions of all 1.31 +// layers from the root down to and including the parent. 1.32 +// - Start with global screen coordinates and unapply all CSS and async 1.33 +// transforms from the root down to and including the parent. 1.34 +// It's helpful to look at https://wiki.mozilla.org/Platform/GFX/APZ#Coordinate_systems 1.35 +// to get a picture of how the various coordinate systems relate to each other. 1.36 +struct ParentLayerPixel {}; 1.37 + 1.38 +typedef gfx::PointTyped<ParentLayerPixel> ParentLayerPoint; 1.39 +typedef gfx::RectTyped<ParentLayerPixel> ParentLayerRect; 1.40 +typedef gfx::SizeTyped<ParentLayerPixel> ParentLayerSize; 1.41 + 1.42 +typedef gfx::IntMarginTyped<ParentLayerPixel> ParentLayerIntMargin; 1.43 +typedef gfx::IntPointTyped<ParentLayerPixel> ParentLayerIntPoint; 1.44 +typedef gfx::IntRectTyped<ParentLayerPixel> ParentLayerIntRect; 1.45 +typedef gfx::IntSizeTyped<ParentLayerPixel> ParentLayerIntSize; 1.46 + 1.47 +typedef gfx::ScaleFactor<CSSPixel, ParentLayerPixel> CSSToParentLayerScale; 1.48 +typedef gfx::ScaleFactor<LayoutDevicePixel, ParentLayerPixel> LayoutDeviceToParentLayerScale; 1.49 +typedef gfx::ScaleFactor<ScreenPixel, ParentLayerPixel> ScreenToParentLayerScale; 1.50 + 1.51 +typedef gfx::ScaleFactor<ParentLayerPixel, LayerPixel> ParentLayerToLayerScale; 1.52 +typedef gfx::ScaleFactor<ParentLayerPixel, ScreenPixel> ParentLayerToScreenScale; 1.53 + 1.54 + 1.55 +namespace layers { 1.56 + 1.57 +/** 1.58 + * The viewport and displayport metrics for the painted frame at the 1.59 + * time of a layer-tree transaction. These metrics are especially 1.60 + * useful for shadow layers, because the metrics values are updated 1.61 + * atomically with new pixels. 1.62 + */ 1.63 +struct FrameMetrics { 1.64 + friend struct IPC::ParamTraits<mozilla::layers::FrameMetrics>; 1.65 +public: 1.66 + // We use IDs to identify frames across processes. 1.67 + typedef uint64_t ViewID; 1.68 + static const ViewID NULL_SCROLL_ID; // This container layer does not scroll. 1.69 + static const ViewID START_SCROLL_ID = 2; // This is the ID that scrolling subframes 1.70 + // will begin at. 1.71 + 1.72 + FrameMetrics() 1.73 + : mCompositionBounds(0, 0, 0, 0) 1.74 + , mDisplayPort(0, 0, 0, 0) 1.75 + , mCriticalDisplayPort(0, 0, 0, 0) 1.76 + , mViewport(0, 0, 0, 0) 1.77 + , mScrollableRect(0, 0, 0, 0) 1.78 + , mResolution(1) 1.79 + , mCumulativeResolution(1) 1.80 + , mTransformScale(1) 1.81 + , mDevPixelsPerCSSPixel(1) 1.82 + , mPresShellId(-1) 1.83 + , mMayHaveTouchListeners(false) 1.84 + , mIsRoot(false) 1.85 + , mHasScrollgrab(false) 1.86 + , mScrollId(NULL_SCROLL_ID) 1.87 + , mScrollOffset(0, 0) 1.88 + , mZoom(1) 1.89 + , mUpdateScrollOffset(false) 1.90 + , mScrollGeneration(0) 1.91 + , mRootCompositionSize(0, 0) 1.92 + , mDisplayPortMargins(0, 0, 0, 0) 1.93 + , mUseDisplayPortMargins(false) 1.94 + {} 1.95 + 1.96 + // Default copy ctor and operator= are fine 1.97 + 1.98 + bool operator==(const FrameMetrics& aOther) const 1.99 + { 1.100 + // mContentDescription is not compared on purpose as it's only used 1.101 + // for debugging. 1.102 + return mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) && 1.103 + mRootCompositionSize == aOther.mRootCompositionSize && 1.104 + mDisplayPort.IsEqualEdges(aOther.mDisplayPort) && 1.105 + mDisplayPortMargins == aOther.mDisplayPortMargins && 1.106 + mUseDisplayPortMargins == aOther.mUseDisplayPortMargins && 1.107 + mCriticalDisplayPort.IsEqualEdges(aOther.mCriticalDisplayPort) && 1.108 + mViewport.IsEqualEdges(aOther.mViewport) && 1.109 + mScrollableRect.IsEqualEdges(aOther.mScrollableRect) && 1.110 + mResolution == aOther.mResolution && 1.111 + mCumulativeResolution == aOther.mCumulativeResolution && 1.112 + mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel && 1.113 + mMayHaveTouchListeners == aOther.mMayHaveTouchListeners && 1.114 + mPresShellId == aOther.mPresShellId && 1.115 + mIsRoot == aOther.mIsRoot && 1.116 + mScrollId == aOther.mScrollId && 1.117 + mScrollOffset == aOther.mScrollOffset && 1.118 + mHasScrollgrab == aOther.mHasScrollgrab && 1.119 + mUpdateScrollOffset == aOther.mUpdateScrollOffset; 1.120 + } 1.121 + bool operator!=(const FrameMetrics& aOther) const 1.122 + { 1.123 + return !operator==(aOther); 1.124 + } 1.125 + 1.126 + bool IsDefault() const 1.127 + { 1.128 + FrameMetrics def; 1.129 + 1.130 + def.mPresShellId = mPresShellId; 1.131 + return (def == *this); 1.132 + } 1.133 + 1.134 + bool IsRootScrollable() const 1.135 + { 1.136 + return mIsRoot; 1.137 + } 1.138 + 1.139 + bool IsScrollable() const 1.140 + { 1.141 + return mScrollId != NULL_SCROLL_ID; 1.142 + } 1.143 + 1.144 + CSSToLayerScale LayersPixelsPerCSSPixel() const 1.145 + { 1.146 + return mCumulativeResolution * mDevPixelsPerCSSPixel; 1.147 + } 1.148 + 1.149 + LayerPoint GetScrollOffsetInLayerPixels() const 1.150 + { 1.151 + return GetScrollOffset() * LayersPixelsPerCSSPixel(); 1.152 + } 1.153 + 1.154 + LayoutDeviceToParentLayerScale GetParentResolution() const 1.155 + { 1.156 + return mCumulativeResolution / mResolution; 1.157 + } 1.158 + 1.159 + // Ensure the scrollableRect is at least as big as the compositionBounds 1.160 + // because the scrollableRect can be smaller if the content is not large 1.161 + // and the scrollableRect hasn't been updated yet. 1.162 + // We move the scrollableRect up because we don't know if we can move it 1.163 + // down. i.e. we know that scrollableRect can go back as far as zero. 1.164 + // but we don't know how much further ahead it can go. 1.165 + CSSRect GetExpandedScrollableRect() const 1.166 + { 1.167 + CSSRect scrollableRect = mScrollableRect; 1.168 + CSSSize compSize = CalculateCompositedSizeInCssPixels(); 1.169 + if (scrollableRect.width < compSize.width) { 1.170 + scrollableRect.x = std::max(0.f, 1.171 + scrollableRect.x - (compSize.width - scrollableRect.width)); 1.172 + scrollableRect.width = compSize.width; 1.173 + } 1.174 + 1.175 + if (scrollableRect.height < compSize.height) { 1.176 + scrollableRect.y = std::max(0.f, 1.177 + scrollableRect.y - (compSize.height - scrollableRect.height)); 1.178 + scrollableRect.height = compSize.height; 1.179 + } 1.180 + 1.181 + return scrollableRect; 1.182 + } 1.183 + 1.184 + // Return the scale factor needed to fit the viewport 1.185 + // into its composition bounds. 1.186 + CSSToScreenScale CalculateIntrinsicScale() const 1.187 + { 1.188 + return CSSToScreenScale(float(mCompositionBounds.width) / float(mViewport.width)); 1.189 + } 1.190 + 1.191 + // Return the scale factor for converting from CSS pixels (for this layer) 1.192 + // to layer pixels of our parent layer. Much as mZoom is used to interface 1.193 + // between inputs we get in screen pixels and quantities in CSS pixels, 1.194 + // this is used to interface between mCompositionBounds and quantities 1.195 + // in CSS pixels. 1.196 + CSSToParentLayerScale GetZoomToParent() const 1.197 + { 1.198 + return mZoom * mTransformScale; 1.199 + } 1.200 + 1.201 + CSSSize CalculateCompositedSizeInCssPixels() const 1.202 + { 1.203 + return mCompositionBounds.Size() / GetZoomToParent(); 1.204 + } 1.205 + 1.206 + CSSRect CalculateCompositedRectInCssPixels() const 1.207 + { 1.208 + return mCompositionBounds / GetZoomToParent(); 1.209 + } 1.210 + 1.211 + void ScrollBy(const CSSPoint& aPoint) 1.212 + { 1.213 + mScrollOffset += aPoint; 1.214 + } 1.215 + 1.216 + void ZoomBy(float aFactor) 1.217 + { 1.218 + mZoom.scale *= aFactor; 1.219 + } 1.220 + 1.221 + void CopyScrollInfoFrom(const FrameMetrics& aOther) 1.222 + { 1.223 + mScrollOffset = aOther.mScrollOffset; 1.224 + mScrollGeneration = aOther.mScrollGeneration; 1.225 + } 1.226 + 1.227 + // --------------------------------------------------------------------------- 1.228 + // The following metrics are all in widget space/device pixels. 1.229 + // 1.230 + 1.231 + // This is the area within the widget that we're compositing to. It is relative 1.232 + // to the layer tree origin. 1.233 + // 1.234 + // This is useful because, on mobile, the viewport and composition dimensions 1.235 + // are not always the same. In this case, we calculate the displayport using 1.236 + // an area bigger than the region we're compositing to. If we used the 1.237 + // viewport dimensions to calculate the displayport, we'd run into situations 1.238 + // where we're prerendering the wrong regions and the content may be clipped, 1.239 + // or too much of it prerendered. If the composition dimensions are the same as the 1.240 + // viewport dimensions, there is no need for this and we can just use the viewport 1.241 + // instead. 1.242 + // 1.243 + // This value is valid for nested scrollable layers as well, and is still 1.244 + // relative to the layer tree origin. This value is provided by Gecko at 1.245 + // layout/paint time. 1.246 + ParentLayerIntRect mCompositionBounds; 1.247 + 1.248 + // --------------------------------------------------------------------------- 1.249 + // The following metrics are all in CSS pixels. They are not in any uniform 1.250 + // space, so each is explained separately. 1.251 + // 1.252 + 1.253 + // The area of a frame's contents that has been painted, relative to the 1.254 + // viewport. It is in the same coordinate space as |mViewport|. For example, 1.255 + // if it is at 0,0, then it's at the same place at the viewport, which is at 1.256 + // the top-left in the layer, and at the same place as the scroll offset of 1.257 + // the document. 1.258 + // 1.259 + // Note that this is structured in such a way that it doesn't depend on the 1.260 + // method layout uses to scroll content. 1.261 + // 1.262 + // May be larger or smaller than |mScrollableRect|. 1.263 + // 1.264 + // To pre-render a margin of 100 CSS pixels around the window, 1.265 + // { x = -100, y = - 100, 1.266 + // width = window.innerWidth + 200, height = window.innerHeight + 200 } 1.267 + CSSRect mDisplayPort; 1.268 + 1.269 + // If non-empty, the area of a frame's contents that is considered critical 1.270 + // to paint. Area outside of this area (i.e. area inside mDisplayPort, but 1.271 + // outside of mCriticalDisplayPort) is considered low-priority, and may be 1.272 + // painted with lower precision, or not painted at all. 1.273 + // 1.274 + // The same restrictions for mDisplayPort apply here. 1.275 + CSSRect mCriticalDisplayPort; 1.276 + 1.277 + // The CSS viewport, which is the dimensions we're using to constrain the 1.278 + // <html> element of this frame, relative to the top-left of the layer. Note 1.279 + // that its offset is structured in such a way that it doesn't depend on the 1.280 + // method layout uses to scroll content. 1.281 + // 1.282 + // This is mainly useful on the root layer, however nested iframes can have 1.283 + // their own viewport, which will just be the size of the window of the 1.284 + // iframe. For layers that don't correspond to a document, this metric is 1.285 + // meaningless and invalid. 1.286 + CSSRect mViewport; 1.287 + 1.288 + // The scrollable bounds of a frame. This is determined by reflow. 1.289 + // Ordinarily the x and y will be 0 and the width and height will be the 1.290 + // size of the element being scrolled. However for RTL pages or elements 1.291 + // the x value may be negative. 1.292 + // 1.293 + // This is relative to the document. It is in the same coordinate space as 1.294 + // |mScrollOffset|, but a different coordinate space than |mViewport| and 1.295 + // |mDisplayPort|. Note also that this coordinate system is understood by 1.296 + // window.scrollTo(). 1.297 + // 1.298 + // This is valid on any layer unless it has no content. 1.299 + CSSRect mScrollableRect; 1.300 + 1.301 + // --------------------------------------------------------------------------- 1.302 + // The following metrics are dimensionless. 1.303 + // 1.304 + 1.305 + // The incremental resolution that the current frame has been painted at 1.306 + // relative to the parent frame's resolution. This information is provided 1.307 + // by Gecko at layout/paint time. 1.308 + ParentLayerToLayerScale mResolution; 1.309 + 1.310 + // The cumulative resolution that the current frame has been painted at. 1.311 + // This is the product of our mResolution and the mResolutions of our parent frames. 1.312 + // This information is provided by Gecko at layout/paint time. 1.313 + LayoutDeviceToLayerScale mCumulativeResolution; 1.314 + 1.315 + // The conversion factor between local screen pixels (the coordinate 1.316 + // system in which APZCs receive input events) and our parent layer's 1.317 + // layer pixels (the coordinate system of mCompositionBounds). 1.318 + // This consists of the scale of the local CSS transform and the 1.319 + // nontransient async transform. 1.320 + // TODO: APZ does not currently work well if there is a CSS transform 1.321 + // on the layer being scrolled that's not just a scale that's 1.322 + // the same in both directions. When we fix this, mTransformScale 1.323 + // will probably need to turn into a matrix. 1.324 + ScreenToParentLayerScale mTransformScale; 1.325 + 1.326 + // The conversion factor between CSS pixels and device pixels for this frame. 1.327 + // This can vary based on a variety of things, such as reflowing-zoom. The 1.328 + // conversion factor for device pixels to layers pixels is just the 1.329 + // resolution. 1.330 + CSSToLayoutDeviceScale mDevPixelsPerCSSPixel; 1.331 + 1.332 + uint32_t mPresShellId; 1.333 + 1.334 + // Whether or not this frame may have touch listeners. 1.335 + bool mMayHaveTouchListeners; 1.336 + 1.337 + // Whether or not this is the root scroll frame for the root content document. 1.338 + bool mIsRoot; 1.339 + 1.340 + // Whether or not this frame is for an element marked 'scrollgrab'. 1.341 + bool mHasScrollgrab; 1.342 + 1.343 +public: 1.344 + void SetScrollOffset(const CSSPoint& aScrollOffset) 1.345 + { 1.346 + mScrollOffset = aScrollOffset; 1.347 + } 1.348 + 1.349 + const CSSPoint& GetScrollOffset() const 1.350 + { 1.351 + return mScrollOffset; 1.352 + } 1.353 + 1.354 + void SetZoom(const CSSToScreenScale& aZoom) 1.355 + { 1.356 + mZoom = aZoom; 1.357 + } 1.358 + 1.359 + CSSToScreenScale GetZoom() const 1.360 + { 1.361 + return mZoom; 1.362 + } 1.363 + 1.364 + void SetScrollOffsetUpdated(uint32_t aScrollGeneration) 1.365 + { 1.366 + mUpdateScrollOffset = true; 1.367 + mScrollGeneration = aScrollGeneration; 1.368 + } 1.369 + 1.370 + bool GetScrollOffsetUpdated() const 1.371 + { 1.372 + return mUpdateScrollOffset; 1.373 + } 1.374 + 1.375 + uint32_t GetScrollGeneration() const 1.376 + { 1.377 + return mScrollGeneration; 1.378 + } 1.379 + 1.380 + const std::string& GetContentDescription() const 1.381 + { 1.382 + return mContentDescription; 1.383 + } 1.384 + 1.385 + void SetContentDescription(const std::string& aContentDescription) 1.386 + { 1.387 + mContentDescription = aContentDescription; 1.388 + } 1.389 + 1.390 + ViewID GetScrollId() const 1.391 + { 1.392 + return mScrollId; 1.393 + } 1.394 + 1.395 + void SetScrollId(ViewID scrollId) 1.396 + { 1.397 + mScrollId = scrollId; 1.398 + } 1.399 + 1.400 + void SetRootCompositionSize(const CSSSize& aRootCompositionSize) 1.401 + { 1.402 + mRootCompositionSize = aRootCompositionSize; 1.403 + } 1.404 + 1.405 + const CSSSize& GetRootCompositionSize() const 1.406 + { 1.407 + return mRootCompositionSize; 1.408 + } 1.409 + 1.410 + void SetDisplayPortMargins(const LayerMargin& aDisplayPortMargins) 1.411 + { 1.412 + mDisplayPortMargins = aDisplayPortMargins; 1.413 + } 1.414 + 1.415 + const LayerMargin& GetDisplayPortMargins() const 1.416 + { 1.417 + return mDisplayPortMargins; 1.418 + } 1.419 + 1.420 + void SetUseDisplayPortMargins() 1.421 + { 1.422 + mUseDisplayPortMargins = true; 1.423 + } 1.424 + 1.425 + bool GetUseDisplayPortMargins() const 1.426 + { 1.427 + return mUseDisplayPortMargins; 1.428 + } 1.429 + 1.430 +private: 1.431 + // New fields from now on should be made private and old fields should 1.432 + // be refactored to be private. 1.433 + 1.434 + // A unique ID assigned to each scrollable frame. 1.435 + ViewID mScrollId; 1.436 + 1.437 + // The position of the top-left of the CSS viewport, relative to the document 1.438 + // (or the document relative to the viewport, if that helps understand it). 1.439 + // 1.440 + // Thus it is relative to the document. It is in the same coordinate space as 1.441 + // |mScrollableRect|, but a different coordinate space than |mViewport| and 1.442 + // |mDisplayPort|. 1.443 + // 1.444 + // It is required that the rect: 1.445 + // { x = mScrollOffset.x, y = mScrollOffset.y, 1.446 + // width = mCompositionBounds.x / mResolution.scale, 1.447 + // height = mCompositionBounds.y / mResolution.scale } 1.448 + // Be within |mScrollableRect|. 1.449 + // 1.450 + // This is valid for any layer, but is always relative to this frame and 1.451 + // not any parents, regardless of parent transforms. 1.452 + CSSPoint mScrollOffset; 1.453 + 1.454 + // The "user zoom". Content is painted by gecko at mResolution * mDevPixelsPerCSSPixel, 1.455 + // but will be drawn to the screen at mZoom. In the steady state, the 1.456 + // two will be the same, but during an async zoom action the two may 1.457 + // diverge. This information is initialized in Gecko but updated in the APZC. 1.458 + CSSToScreenScale mZoom; 1.459 + 1.460 + // Whether mScrollOffset was updated by something other than the APZ code, and 1.461 + // if the APZC receiving this metrics should update its local copy. 1.462 + bool mUpdateScrollOffset; 1.463 + // The scroll generation counter used to acknowledge the scroll offset update. 1.464 + uint32_t mScrollGeneration; 1.465 + 1.466 + // A description of the content element corresponding to this frame. 1.467 + // This is empty unless the apz.printtree pref is turned on. 1.468 + std::string mContentDescription; 1.469 + 1.470 + // The size of the root scrollable's composition bounds, but in local CSS pixels. 1.471 + CSSSize mRootCompositionSize; 1.472 + 1.473 + // A display port expressed as layer margins that apply to the rect of what 1.474 + // is drawn of the scrollable element. 1.475 + LayerMargin mDisplayPortMargins; 1.476 + 1.477 + // If this is true then we use the display port margins on this metrics, 1.478 + // otherwise use the display port rect. 1.479 + bool mUseDisplayPortMargins; 1.480 +}; 1.481 + 1.482 +/** 1.483 + * This class allows us to uniquely identify a scrollable layer. The 1.484 + * mLayersId identifies the layer tree (corresponding to a child process 1.485 + * and/or tab) that the scrollable layer belongs to. The mPresShellId 1.486 + * is a temporal identifier (corresponding to the document loaded that 1.487 + * contains the scrollable layer, which may change over time). The 1.488 + * mScrollId corresponds to the actual frame that is scrollable. 1.489 + */ 1.490 +struct ScrollableLayerGuid { 1.491 + uint64_t mLayersId; 1.492 + uint32_t mPresShellId; 1.493 + FrameMetrics::ViewID mScrollId; 1.494 + 1.495 + ScrollableLayerGuid() 1.496 + : mLayersId(0) 1.497 + , mPresShellId(0) 1.498 + , mScrollId(0) 1.499 + { 1.500 + MOZ_COUNT_CTOR(ScrollableLayerGuid); 1.501 + } 1.502 + 1.503 + ScrollableLayerGuid(uint64_t aLayersId, uint32_t aPresShellId, 1.504 + FrameMetrics::ViewID aScrollId) 1.505 + : mLayersId(aLayersId) 1.506 + , mPresShellId(aPresShellId) 1.507 + , mScrollId(aScrollId) 1.508 + { 1.509 + MOZ_COUNT_CTOR(ScrollableLayerGuid); 1.510 + } 1.511 + 1.512 + ScrollableLayerGuid(uint64_t aLayersId, const FrameMetrics& aMetrics) 1.513 + : mLayersId(aLayersId) 1.514 + , mPresShellId(aMetrics.mPresShellId) 1.515 + , mScrollId(aMetrics.GetScrollId()) 1.516 + { 1.517 + MOZ_COUNT_CTOR(ScrollableLayerGuid); 1.518 + } 1.519 + 1.520 + ~ScrollableLayerGuid() 1.521 + { 1.522 + MOZ_COUNT_DTOR(ScrollableLayerGuid); 1.523 + } 1.524 + 1.525 + bool operator==(const ScrollableLayerGuid& other) const 1.526 + { 1.527 + return mLayersId == other.mLayersId 1.528 + && mPresShellId == other.mPresShellId 1.529 + && mScrollId == other.mScrollId; 1.530 + } 1.531 + 1.532 + bool operator!=(const ScrollableLayerGuid& other) const 1.533 + { 1.534 + return !(*this == other); 1.535 + } 1.536 +}; 1.537 + 1.538 +template <int LogLevel> 1.539 +gfx::Log<LogLevel>& operator<<(gfx::Log<LogLevel>& log, const ScrollableLayerGuid& aGuid) { 1.540 + return log << '(' << aGuid.mLayersId << ',' << aGuid.mPresShellId << ',' << aGuid.mScrollId << ')'; 1.541 +} 1.542 + 1.543 +struct ZoomConstraints { 1.544 + bool mAllowZoom; 1.545 + bool mAllowDoubleTapZoom; 1.546 + CSSToScreenScale mMinZoom; 1.547 + CSSToScreenScale mMaxZoom; 1.548 + 1.549 + ZoomConstraints() 1.550 + : mAllowZoom(true) 1.551 + , mAllowDoubleTapZoom(true) 1.552 + { 1.553 + MOZ_COUNT_CTOR(ZoomConstraints); 1.554 + } 1.555 + 1.556 + ZoomConstraints(bool aAllowZoom, 1.557 + bool aAllowDoubleTapZoom, 1.558 + const CSSToScreenScale& aMinZoom, 1.559 + const CSSToScreenScale& aMaxZoom) 1.560 + : mAllowZoom(aAllowZoom) 1.561 + , mAllowDoubleTapZoom(aAllowDoubleTapZoom) 1.562 + , mMinZoom(aMinZoom) 1.563 + , mMaxZoom(aMaxZoom) 1.564 + { 1.565 + MOZ_COUNT_CTOR(ZoomConstraints); 1.566 + } 1.567 + 1.568 + ~ZoomConstraints() 1.569 + { 1.570 + MOZ_COUNT_DTOR(ZoomConstraints); 1.571 + } 1.572 + 1.573 + bool operator==(const ZoomConstraints& other) const 1.574 + { 1.575 + return mAllowZoom == other.mAllowZoom 1.576 + && mAllowDoubleTapZoom == other.mAllowDoubleTapZoom 1.577 + && mMinZoom == other.mMinZoom 1.578 + && mMaxZoom == other.mMaxZoom; 1.579 + } 1.580 + 1.581 + bool operator!=(const ZoomConstraints& other) const 1.582 + { 1.583 + return !(*this == other); 1.584 + } 1.585 +}; 1.586 + 1.587 +} 1.588 +} 1.589 + 1.590 +#endif /* GFX_FRAMEMETRICS_H */