2012-07-31 04:42:26 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef GFX_FRAMEMETRICS_H
|
|
|
|
#define GFX_FRAMEMETRICS_H
|
|
|
|
|
2013-03-04 18:37:43 +04:00
|
|
|
#include "gfxPoint.h"
|
2013-03-04 04:25:26 +04:00
|
|
|
#include "gfxTypes.h"
|
2013-03-04 18:37:43 +04:00
|
|
|
#include "nsRect.h"
|
|
|
|
#include "mozilla/gfx/Rect.h"
|
2013-05-31 05:30:13 +04:00
|
|
|
#include "Units.h"
|
2012-07-31 04:42:26 +04:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace layers {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The viewport and displayport metrics for the painted frame at the
|
|
|
|
* time of a layer-tree transaction. These metrics are especially
|
|
|
|
* useful for shadow layers, because the metrics values are updated
|
|
|
|
* atomically with new pixels.
|
|
|
|
*/
|
2013-05-30 01:59:24 +04:00
|
|
|
struct FrameMetrics {
|
2012-07-31 04:42:26 +04:00
|
|
|
public:
|
|
|
|
// We use IDs to identify frames across processes.
|
2012-08-22 19:56:38 +04:00
|
|
|
typedef uint64_t ViewID;
|
2012-07-31 04:42:26 +04:00
|
|
|
static const ViewID NULL_SCROLL_ID; // This container layer does not scroll.
|
|
|
|
static const ViewID ROOT_SCROLL_ID; // This is the root scroll frame.
|
|
|
|
static const ViewID START_SCROLL_ID; // This is the ID that scrolling subframes
|
|
|
|
// will begin at.
|
|
|
|
|
|
|
|
FrameMetrics()
|
2012-09-29 06:16:34 +04:00
|
|
|
: mCompositionBounds(0, 0, 0, 0)
|
|
|
|
, mDisplayPort(0, 0, 0, 0)
|
2012-11-22 02:34:18 +04:00
|
|
|
, mCriticalDisplayPort(0, 0, 0, 0)
|
2012-09-29 06:16:34 +04:00
|
|
|
, mViewport(0, 0, 0, 0)
|
|
|
|
, mScrollOffset(0, 0)
|
2012-07-31 04:42:26 +04:00
|
|
|
, mScrollId(NULL_SCROLL_ID)
|
2012-09-29 06:16:34 +04:00
|
|
|
, mScrollableRect(0, 0, 0, 0)
|
2013-06-22 01:03:56 +04:00
|
|
|
, mResolution(1)
|
|
|
|
, mZoom(1)
|
2012-09-29 06:16:34 +04:00
|
|
|
, mDevPixelsPerCSSPixel(1)
|
2012-08-22 08:37:06 +04:00
|
|
|
, mMayHaveTouchListeners(false)
|
2013-05-24 05:43:36 +04:00
|
|
|
, mPresShellId(-1)
|
2012-07-31 04:42:26 +04:00
|
|
|
{}
|
|
|
|
|
|
|
|
// Default copy ctor and operator= are fine
|
|
|
|
|
|
|
|
bool operator==(const FrameMetrics& aOther) const
|
|
|
|
{
|
2012-10-04 03:51:38 +04:00
|
|
|
return mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) &&
|
|
|
|
mDisplayPort.IsEqualEdges(aOther.mDisplayPort) &&
|
2012-11-22 02:34:18 +04:00
|
|
|
mCriticalDisplayPort.IsEqualEdges(aOther.mCriticalDisplayPort) &&
|
2012-10-04 03:51:38 +04:00
|
|
|
mViewport.IsEqualEdges(aOther.mViewport) &&
|
|
|
|
mScrollOffset == aOther.mScrollOffset &&
|
|
|
|
mScrollId == aOther.mScrollId &&
|
|
|
|
mScrollableRect.IsEqualEdges(aOther.mScrollableRect) &&
|
|
|
|
mResolution == aOther.mResolution &&
|
|
|
|
mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel &&
|
2013-05-24 05:43:36 +04:00
|
|
|
mMayHaveTouchListeners == aOther.mMayHaveTouchListeners &&
|
|
|
|
mPresShellId == aOther.mPresShellId;
|
2012-07-31 04:42:26 +04:00
|
|
|
}
|
|
|
|
bool operator!=(const FrameMetrics& aOther) const
|
|
|
|
{
|
|
|
|
return !operator==(aOther);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsDefault() const
|
|
|
|
{
|
2013-05-24 05:43:36 +04:00
|
|
|
FrameMetrics def;
|
|
|
|
|
|
|
|
def.mPresShellId = mPresShellId;
|
|
|
|
return (def == *this);
|
2012-07-31 04:42:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool IsRootScrollable() const
|
|
|
|
{
|
|
|
|
return mScrollId == ROOT_SCROLL_ID;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsScrollable() const
|
|
|
|
{
|
|
|
|
return mScrollId != NULL_SCROLL_ID;
|
|
|
|
}
|
|
|
|
|
2013-06-22 01:03:56 +04:00
|
|
|
CSSToLayerScale LayersPixelsPerCSSPixel() const
|
2012-09-29 06:16:34 +04:00
|
|
|
{
|
|
|
|
return mResolution * mDevPixelsPerCSSPixel;
|
|
|
|
}
|
|
|
|
|
2013-06-22 01:03:56 +04:00
|
|
|
LayerPoint GetScrollOffsetInLayerPixels() const
|
2012-09-29 06:16:34 +04:00
|
|
|
{
|
2013-06-22 01:03:56 +04:00
|
|
|
return mScrollOffset * LayersPixelsPerCSSPixel();
|
2012-09-29 06:16:34 +04:00
|
|
|
}
|
|
|
|
|
2013-06-26 17:53:51 +04:00
|
|
|
/**
|
|
|
|
* Return the scale factor needed to fit the viewport
|
|
|
|
* into its composition bounds.
|
|
|
|
*/
|
|
|
|
CSSToScreenScale CalculateIntrinsicScale() const
|
|
|
|
{
|
|
|
|
return CSSToScreenScale(float(mCompositionBounds.width) / float(mViewport.width));
|
|
|
|
}
|
|
|
|
|
2013-06-26 17:54:14 +04:00
|
|
|
/**
|
|
|
|
* Return the resolution that content should be rendered at given
|
|
|
|
* the configuration in this metrics object: viewport dimensions,
|
|
|
|
* zoom factor, etc. (The mResolution member of this metrics is
|
|
|
|
* ignored.)
|
|
|
|
*/
|
|
|
|
CSSToScreenScale CalculateResolution() const
|
|
|
|
{
|
|
|
|
return CalculateIntrinsicScale() * mZoom;
|
|
|
|
}
|
|
|
|
|
2013-06-26 17:54:49 +04:00
|
|
|
CSSRect CalculateCompositedRectInCssPixels() const
|
|
|
|
{
|
|
|
|
return CSSRect(gfx::RoundedIn(mCompositionBounds / CalculateResolution()));
|
|
|
|
}
|
|
|
|
|
2012-09-29 06:16:34 +04:00
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// The following metrics are all in widget space/device pixels.
|
|
|
|
//
|
|
|
|
|
|
|
|
// This is the area within the widget that we're compositing to, which means
|
|
|
|
// that it is the visible region of this frame. It is not relative to
|
|
|
|
// anything.
|
|
|
|
// So { 0, 0, [compositeArea.width], [compositeArea.height] }.
|
|
|
|
//
|
|
|
|
// This is useful because, on mobile, the viewport and composition dimensions
|
|
|
|
// are not always the same. In this case, we calculate the displayport using
|
|
|
|
// an area bigger than the region we're compositing to. If we used the
|
|
|
|
// viewport dimensions to calculate the displayport, we'd run into situations
|
|
|
|
// where we're prerendering the wrong regions and the content may be clipped,
|
|
|
|
// or too much of it prerendered. If the displayport is the same as the
|
|
|
|
// viewport, there is no need for this and we can just use the viewport
|
|
|
|
// instead.
|
|
|
|
//
|
|
|
|
// This is only valid on the root layer. Nested iframes do not need this
|
|
|
|
// metric as they do not have a displayport set. See bug 775452.
|
2013-06-15 00:11:29 +04:00
|
|
|
ScreenIntRect mCompositionBounds;
|
2012-09-29 06:16:34 +04:00
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// The following metrics are all in CSS pixels. They are not in any uniform
|
|
|
|
// space, so each is explained separately.
|
|
|
|
//
|
|
|
|
|
|
|
|
// The area of a frame's contents that has been painted, relative to the
|
|
|
|
// viewport. It is in the same coordinate space as |mViewport|. For example,
|
|
|
|
// if it is at 0,0, then it's at the same place at the viewport, which is at
|
|
|
|
// the top-left in the layer, and at the same place as the scroll offset of
|
|
|
|
// the document.
|
|
|
|
//
|
|
|
|
// Note that this is structured in such a way that it doesn't depend on the
|
|
|
|
// method layout uses to scroll content.
|
|
|
|
//
|
|
|
|
// May be larger or smaller than |mScrollableRect|.
|
|
|
|
//
|
|
|
|
// To pre-render a margin of 100 CSS pixels around the window,
|
|
|
|
// { x = -100, y = - 100,
|
2013-07-03 17:04:10 +04:00
|
|
|
// width = window.innerWidth + 200, height = window.innerHeight + 200 }
|
2012-09-29 06:16:34 +04:00
|
|
|
//
|
|
|
|
// This is only valid on the root layer. Nested iframes do not have a
|
|
|
|
// displayport set on them. See bug 775452.
|
2013-06-10 17:05:42 +04:00
|
|
|
CSSRect mDisplayPort;
|
2012-09-29 06:16:34 +04:00
|
|
|
|
2012-11-22 02:34:18 +04:00
|
|
|
// If non-empty, the area of a frame's contents that is considered critical
|
|
|
|
// to paint. Area outside of this area (i.e. area inside mDisplayPort, but
|
|
|
|
// outside of mCriticalDisplayPort) is considered low-priority, and may be
|
|
|
|
// painted with lower precision, or not painted at all.
|
|
|
|
//
|
|
|
|
// The same restrictions for mDisplayPort apply here.
|
2013-06-10 17:05:42 +04:00
|
|
|
CSSRect mCriticalDisplayPort;
|
2012-11-22 02:34:18 +04:00
|
|
|
|
2012-09-29 06:16:34 +04:00
|
|
|
// The CSS viewport, which is the dimensions we're using to constrain the
|
|
|
|
// <html> element of this frame, relative to the top-left of the layer. Note
|
|
|
|
// that its offset is structured in such a way that it doesn't depend on the
|
|
|
|
// method layout uses to scroll content.
|
|
|
|
//
|
|
|
|
// This is mainly useful on the root layer, however nested iframes can have
|
|
|
|
// their own viewport, which will just be the size of the window of the
|
|
|
|
// iframe. For layers that don't correspond to a document, this metric is
|
|
|
|
// meaningless and invalid.
|
2013-06-10 17:05:43 +04:00
|
|
|
CSSRect mViewport;
|
2012-09-29 06:16:34 +04:00
|
|
|
|
|
|
|
// The position of the top-left of the CSS viewport, relative to the document
|
|
|
|
// (or the document relative to the viewport, if that helps understand it).
|
|
|
|
//
|
|
|
|
// Thus it is relative to the document. It is in the same coordinate space as
|
|
|
|
// |mScrollableRect|, but a different coordinate space than |mViewport| and
|
|
|
|
// |mDisplayPort|.
|
|
|
|
//
|
|
|
|
// It is required that the rect:
|
|
|
|
// { x = mScrollOffset.x, y = mScrollOffset.y,
|
2013-06-22 01:03:56 +04:00
|
|
|
// width = mCompositionBounds.x / mResolution.scale,
|
|
|
|
// height = mCompositionBounds.y / mResolution.scale }
|
2012-09-29 06:16:34 +04:00
|
|
|
// Be within |mScrollableRect|.
|
|
|
|
//
|
|
|
|
// This is valid for any layer, but is always relative to this frame and
|
|
|
|
// not any parents, regardless of parent transforms.
|
2013-06-10 17:05:43 +04:00
|
|
|
CSSPoint mScrollOffset;
|
2012-09-29 06:16:34 +04:00
|
|
|
|
|
|
|
// A unique ID assigned to each scrollable frame (unless this is
|
|
|
|
// ROOT_SCROLL_ID, in which case it is not unique).
|
2012-07-31 04:42:26 +04:00
|
|
|
ViewID mScrollId;
|
|
|
|
|
2012-09-29 06:16:34 +04:00
|
|
|
// The scrollable bounds of a frame. This is determined by reflow.
|
|
|
|
// For the top-level |window|,
|
|
|
|
// { x = window.scrollX, y = window.scrollY, // could be 0, 0
|
|
|
|
// width = window.innerWidth, height = window.innerHeight }
|
|
|
|
//
|
|
|
|
// This is relative to the document. It is in the same coordinate space as
|
|
|
|
// |mScrollOffset|, but a different coordinate space than |mViewport| and
|
|
|
|
// |mDisplayPort|. Note also that this coordinate system is understood by
|
|
|
|
// window.scrollTo().
|
|
|
|
//
|
|
|
|
// This is valid on any layer unless it has no content.
|
2013-06-10 17:05:43 +04:00
|
|
|
CSSRect mScrollableRect;
|
2012-07-31 04:42:26 +04:00
|
|
|
|
2012-09-29 06:16:38 +04:00
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// The following metrics are dimensionless.
|
|
|
|
//
|
|
|
|
|
|
|
|
// The resolution, along both axes, that the current frame has been painted
|
|
|
|
// at.
|
|
|
|
//
|
|
|
|
// Every time this frame is composited and the compositor samples its
|
|
|
|
// transform, this metric is used to create a transform which is
|
|
|
|
// post-multiplied into the parent's transform. Since this only happens when
|
|
|
|
// we walk the layer tree, the resulting transform isn't stored here. Thus the
|
|
|
|
// resolution of parent layers is opaque to this metric.
|
2013-06-22 01:03:56 +04:00
|
|
|
LayoutDeviceToLayerScale mResolution;
|
2012-08-22 08:37:06 +04:00
|
|
|
|
2012-10-12 09:46:24 +04:00
|
|
|
// The resolution-independent "user zoom". For example, if a page
|
|
|
|
// configures the viewport to a zoom value of 2x, then this member
|
|
|
|
// will always be 2.0 no matter what the viewport or composition
|
|
|
|
// bounds.
|
2012-09-29 06:16:38 +04:00
|
|
|
//
|
2013-07-03 17:04:10 +04:00
|
|
|
// In the steady state (no animations), the following is usually true
|
2012-10-12 09:46:24 +04:00
|
|
|
//
|
|
|
|
// intrinsicScale = (mCompositionBounds / mViewport)
|
2013-07-03 17:04:10 +04:00
|
|
|
// mResolution = mZoom * intrinsicScale / mDevPixelsPerCSSPixel
|
2012-10-12 09:46:24 +04:00
|
|
|
//
|
|
|
|
// When this is not true, we're probably asynchronously sampling a
|
|
|
|
// zoom animation for content.
|
2013-06-22 01:03:56 +04:00
|
|
|
ScreenToScreenScale mZoom;
|
2012-09-29 06:16:38 +04:00
|
|
|
|
2012-09-29 06:16:34 +04:00
|
|
|
// The conversion factor between CSS pixels and device pixels for this frame.
|
|
|
|
// This can vary based on a variety of things, such as reflowing-zoom. The
|
|
|
|
// conversion factor for device pixels to layers pixels is just the
|
|
|
|
// resolution.
|
2013-06-22 01:03:56 +04:00
|
|
|
CSSToLayoutDeviceScale mDevPixelsPerCSSPixel;
|
2012-09-29 06:16:34 +04:00
|
|
|
|
2012-08-22 08:37:06 +04:00
|
|
|
// Whether or not this frame may have touch listeners.
|
|
|
|
bool mMayHaveTouchListeners;
|
2013-05-24 05:43:36 +04:00
|
|
|
|
|
|
|
uint32_t mPresShellId;
|
2012-07-31 04:42:26 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* GFX_FRAMEMETRICS_H */
|