summaryrefslogtreecommitdiffstats
path: root/gfx/wr/webrender_api/src/units.rs
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/wr/webrender_api/src/units.rs')
-rw-r--r--gfx/wr/webrender_api/src/units.rs346
1 files changed, 346 insertions, 0 deletions
diff --git a/gfx/wr/webrender_api/src/units.rs b/gfx/wr/webrender_api/src/units.rs
new file mode 100644
index 0000000000..2d4cc34aab
--- /dev/null
+++ b/gfx/wr/webrender_api/src/units.rs
@@ -0,0 +1,346 @@
+/* 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/. */
+
+//! A collection of coordinate spaces and their corresponding Point, Size and Rect types.
+//!
+//! Physical pixels take into account the device pixel ratio and their dimensions tend
+//! to correspond to the allocated size of resources in memory, while logical pixels
+//! don't have the device pixel ratio applied which means they are agnostic to the usage
+//! of hidpi screens and the like.
+//!
+//! The terms "layer" and "stacking context" can be used interchangeably
+//! in the context of coordinate systems.
+
+pub use app_units::Au;
+use euclid::{Length, Rect, Scale, Size2D, Transform3D, Translation2D};
+use euclid::{Point2D, Point3D, Vector2D, Vector3D, SideOffsets2D, Box2D};
+use euclid::HomogeneousVector;
+use peek_poke::PeekPoke;
+// local imports
+use crate::image::DirtyRect;
+
+/// Geometry in the coordinate system of the render target (screen or intermediate
+/// surface) in physical pixels.
+#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
+pub struct DevicePixel;
+
+pub type DeviceIntRect = Box2D<i32, DevicePixel>;
+pub type DeviceIntPoint = Point2D<i32, DevicePixel>;
+pub type DeviceIntSize = Size2D<i32, DevicePixel>;
+pub type DeviceIntLength = Length<i32, DevicePixel>;
+pub type DeviceIntSideOffsets = SideOffsets2D<i32, DevicePixel>;
+pub type DeviceIntVector2D = Vector2D<i32, DevicePixel>;
+
+pub type DeviceRect = Box2D<f32, DevicePixel>;
+pub type DeviceBox2D = Box2D<f32, DevicePixel>;
+pub type DevicePoint = Point2D<f32, DevicePixel>;
+pub type DeviceVector2D = Vector2D<f32, DevicePixel>;
+pub type DeviceSize = Size2D<f32, DevicePixel>;
+pub type DeviceHomogeneousVector = HomogeneousVector<f32, DevicePixel>;
+
+/// Geometry in the coordinate system of the framebuffer in physical pixels.
+/// It's Y-flipped comparing to DevicePixel.
+#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
+pub struct FramebufferPixel;
+
+pub type FramebufferIntPoint = Point2D<i32, FramebufferPixel>;
+pub type FramebufferIntSize = Size2D<i32, FramebufferPixel>;
+pub type FramebufferIntRect = Box2D<i32, FramebufferPixel>;
+
+/// Geometry in the coordinate system of a Picture (intermediate
+/// surface) in physical pixels.
+#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
+pub struct PicturePixel;
+
+pub type PictureIntRect = Box2D<i32, PicturePixel>;
+pub type PictureIntPoint = Point2D<i32, PicturePixel>;
+pub type PictureIntSize = Size2D<i32, PicturePixel>;
+pub type PictureRect = Box2D<f32, PicturePixel>;
+pub type PicturePoint = Point2D<f32, PicturePixel>;
+pub type PictureSize = Size2D<f32, PicturePixel>;
+pub type PicturePoint3D = Point3D<f32, PicturePixel>;
+pub type PictureVector2D = Vector2D<f32, PicturePixel>;
+pub type PictureVector3D = Vector3D<f32, PicturePixel>;
+pub type PictureBox2D = Box2D<f32, PicturePixel>;
+
+/// Geometry gets rasterized in a given root coordinate space. This
+/// is often the root spatial node (world space), but may be a local
+/// space for a variety of reasons (e.g. perspective).
+#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
+pub struct RasterPixel;
+
+pub type RasterIntRect = Box2D<i32, RasterPixel>;
+pub type RasterIntPoint = Point2D<i32, RasterPixel>;
+pub type RasterIntSize = Size2D<i32, RasterPixel>;
+pub type RasterRect = Box2D<f32, RasterPixel>;
+pub type RasterPoint = Point2D<f32, RasterPixel>;
+pub type RasterSize = Size2D<f32, RasterPixel>;
+pub type RasterPoint3D = Point3D<f32, RasterPixel>;
+pub type RasterVector2D = Vector2D<f32, RasterPixel>;
+pub type RasterVector3D = Vector3D<f32, RasterPixel>;
+
+/// Geometry in a stacking context's local coordinate space (logical pixels).
+#[derive(Hash, Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Ord, PartialOrd, Deserialize, Serialize, PeekPoke)]
+pub struct LayoutPixel;
+
+pub type LayoutRect = Box2D<f32, LayoutPixel>;
+pub type LayoutPoint = Point2D<f32, LayoutPixel>;
+pub type LayoutPoint3D = Point3D<f32, LayoutPixel>;
+pub type LayoutVector2D = Vector2D<f32, LayoutPixel>;
+pub type LayoutVector3D = Vector3D<f32, LayoutPixel>;
+pub type LayoutSize = Size2D<f32, LayoutPixel>;
+pub type LayoutSideOffsets = SideOffsets2D<f32, LayoutPixel>;
+
+pub type LayoutIntRect = Box2D<i32, LayoutPixel>;
+pub type LayoutIntPoint = Point2D<i32, LayoutPixel>;
+pub type LayoutIntSize = Size2D<i32, LayoutPixel>;
+
+/// Geometry in the document's coordinate space (logical pixels).
+#[derive(Hash, Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
+pub struct WorldPixel;
+
+pub type WorldRect = Box2D<f32, WorldPixel>;
+pub type WorldIntRect = Box2D<i32, WorldPixel>;
+pub type WorldPoint = Point2D<f32, WorldPixel>;
+pub type WorldSize = Size2D<f32, WorldPixel>;
+pub type WorldPoint3D = Point3D<f32, WorldPixel>;
+pub type WorldVector2D = Vector2D<f32, WorldPixel>;
+pub type WorldVector3D = Vector3D<f32, WorldPixel>;
+
+/// Offset in number of tiles.
+#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
+pub struct Tiles;
+pub type TileOffset = Point2D<i32, Tiles>;
+pub type TileRange = Box2D<i32, Tiles>;
+
+/// Scaling ratio from world pixels to device pixels.
+pub type DevicePixelScale = Scale<f32, WorldPixel, DevicePixel>;
+/// Scaling ratio from layout to world. Used for cases where we know the layout
+/// is in world space, or specifically want to treat it this way.
+pub type LayoutToWorldScale = Scale<f32, LayoutPixel, WorldPixel>;
+/// A complete scaling ratio from layout space to device pixel space.
+pub type LayoutToDeviceScale = Scale<f32, LayoutPixel, DevicePixel>;
+
+pub type LayoutTransform = Transform3D<f32, LayoutPixel, LayoutPixel>;
+pub type LayoutToWorldTransform = Transform3D<f32, LayoutPixel, WorldPixel>;
+pub type WorldToLayoutTransform = Transform3D<f32, WorldPixel, LayoutPixel>;
+
+pub type LayoutToPictureTransform = Transform3D<f32, LayoutPixel, PicturePixel>;
+pub type PictureToLayoutTransform = Transform3D<f32, PicturePixel, LayoutPixel>;
+
+pub type LayoutToRasterTransform = Transform3D<f32, LayoutPixel, RasterPixel>;
+pub type RasterToLayoutTransform = Transform3D<f32, RasterPixel, LayoutPixel>;
+
+pub type PictureToRasterTransform = Transform3D<f32, PicturePixel, RasterPixel>;
+pub type RasterToPictureTransform = Transform3D<f32, RasterPixel, PicturePixel>;
+
+/// Scaling ratio from picture pixels to raster pixels (e.g. if scaling a picture surface up/down).
+pub type RasterPixelScale = Scale<f32, PicturePixel, RasterPixel>;
+
+// Fixed position coordinates, to avoid float precision errors.
+pub type LayoutPointAu = Point2D<Au, LayoutPixel>;
+pub type LayoutRectAu = Box2D<Au, LayoutPixel>;
+pub type LayoutSizeAu = Size2D<Au, LayoutPixel>;
+pub type LayoutVector2DAu = Vector2D<Au, LayoutPixel>;
+pub type LayoutSideOffsetsAu = SideOffsets2D<Au, LayoutPixel>;
+
+pub type ImageDirtyRect = DirtyRect<i32, DevicePixel>;
+pub type BlobDirtyRect = DirtyRect<i32, LayoutPixel>;
+
+pub type BlobToDeviceTranslation = Translation2D<i32, LayoutPixel, DevicePixel>;
+
+/// Stores two coordinates in texel space. The coordinates
+/// are stored in texel coordinates because the texture atlas
+/// may grow. Storing them as texel coords and normalizing
+/// the UVs in the vertex shader means nothing needs to be
+/// updated on the CPU when the texture size changes.
+#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct TexelRect {
+ pub uv0: DevicePoint,
+ pub uv1: DevicePoint,
+}
+
+impl TexelRect {
+ pub fn new(u0: f32, v0: f32, u1: f32, v1: f32) -> Self {
+ TexelRect {
+ uv0: DevicePoint::new(u0, v0),
+ uv1: DevicePoint::new(u1, v1),
+ }
+ }
+
+ pub fn invalid() -> Self {
+ TexelRect {
+ uv0: DevicePoint::new(-1.0, -1.0),
+ uv1: DevicePoint::new(-1.0, -1.0),
+ }
+ }
+}
+
+impl Into<TexelRect> for DeviceIntRect {
+ fn into(self) -> TexelRect {
+ TexelRect {
+ uv0: self.min.to_f32(),
+ uv1: self.max.to_f32(),
+ }
+ }
+}
+
+const MAX_AU_FLOAT: f32 = 1.0e6;
+
+pub trait AuHelpers<T> {
+ fn from_au(data: T) -> Self;
+ fn to_au(&self) -> T;
+}
+
+impl AuHelpers<LayoutSizeAu> for LayoutSize {
+ fn from_au(size: LayoutSizeAu) -> Self {
+ LayoutSize::new(
+ size.width.to_f32_px(),
+ size.height.to_f32_px(),
+ )
+ }
+
+ fn to_au(&self) -> LayoutSizeAu {
+ let width = self.width.min(2.0 * MAX_AU_FLOAT);
+ let height = self.height.min(2.0 * MAX_AU_FLOAT);
+
+ LayoutSizeAu::new(
+ Au::from_f32_px(width),
+ Au::from_f32_px(height),
+ )
+ }
+}
+
+impl AuHelpers<LayoutVector2DAu> for LayoutVector2D {
+ fn from_au(size: LayoutVector2DAu) -> Self {
+ LayoutVector2D::new(
+ size.x.to_f32_px(),
+ size.y.to_f32_px(),
+ )
+ }
+
+ fn to_au(&self) -> LayoutVector2DAu {
+ LayoutVector2DAu::new(
+ Au::from_f32_px(self.x),
+ Au::from_f32_px(self.y),
+ )
+ }
+}
+
+impl AuHelpers<LayoutPointAu> for LayoutPoint {
+ fn from_au(point: LayoutPointAu) -> Self {
+ LayoutPoint::new(
+ point.x.to_f32_px(),
+ point.y.to_f32_px(),
+ )
+ }
+
+ fn to_au(&self) -> LayoutPointAu {
+ let x = self.x.min(MAX_AU_FLOAT).max(-MAX_AU_FLOAT);
+ let y = self.y.min(MAX_AU_FLOAT).max(-MAX_AU_FLOAT);
+
+ LayoutPointAu::new(
+ Au::from_f32_px(x),
+ Au::from_f32_px(y),
+ )
+ }
+}
+
+impl AuHelpers<LayoutRectAu> for LayoutRect {
+ fn from_au(rect: LayoutRectAu) -> Self {
+ LayoutRect {
+ min: LayoutPoint::from_au(rect.min),
+ max: LayoutPoint::from_au(rect.max),
+ }
+ }
+
+ fn to_au(&self) -> LayoutRectAu {
+ LayoutRectAu {
+ min: self.min.to_au(),
+ max: self.max.to_au(),
+ }
+ }
+}
+
+impl AuHelpers<LayoutSideOffsetsAu> for LayoutSideOffsets {
+ fn from_au(offsets: LayoutSideOffsetsAu) -> Self {
+ LayoutSideOffsets::new(
+ offsets.top.to_f32_px(),
+ offsets.right.to_f32_px(),
+ offsets.bottom.to_f32_px(),
+ offsets.left.to_f32_px(),
+ )
+ }
+
+ fn to_au(&self) -> LayoutSideOffsetsAu {
+ LayoutSideOffsetsAu::new(
+ Au::from_f32_px(self.top),
+ Au::from_f32_px(self.right),
+ Au::from_f32_px(self.bottom),
+ Au::from_f32_px(self.left),
+ )
+ }
+}
+
+pub trait RectExt {
+ type Point;
+ fn top_left(&self) -> Self::Point;
+ fn top_right(&self) -> Self::Point;
+ fn bottom_left(&self) -> Self::Point;
+ fn bottom_right(&self) -> Self::Point;
+}
+
+impl<U> RectExt for Rect<f32, U> {
+ type Point = Point2D<f32, U>;
+ fn top_left(&self) -> Self::Point {
+ self.min()
+ }
+ fn top_right(&self) -> Self::Point {
+ Point2D::new(self.max_x(), self.min_y())
+ }
+ fn bottom_left(&self) -> Self::Point {
+ Point2D::new(self.min_x(), self.max_y())
+ }
+ fn bottom_right(&self) -> Self::Point {
+ self.max()
+ }
+}
+
+impl<U> RectExt for Box2D<f32, U> {
+ type Point = Point2D<f32, U>;
+ fn top_left(&self) -> Self::Point {
+ self.min
+ }
+ fn top_right(&self) -> Self::Point {
+ Point2D::new(self.max.x, self.min.y)
+ }
+ fn bottom_left(&self) -> Self::Point {
+ Point2D::new(self.min.x, self.max.y)
+ }
+ fn bottom_right(&self) -> Self::Point {
+ self.max
+ }
+}
+
+// A few helpers to convert to cast between coordinate spaces that are often equivalent.
+
+#[inline]
+pub fn layout_rect_as_picture_rect(layout_rect: &LayoutRect) -> PictureRect {
+ layout_rect.cast_unit()
+}
+
+#[inline]
+pub fn layout_vector_as_picture_vector(layout_vector: LayoutVector2D) -> PictureVector2D {
+ layout_vector.cast_unit()
+}
+
+#[inline]
+pub fn device_size_as_framebuffer_size(framebuffer_size: DeviceIntSize) -> FramebufferIntSize {
+ framebuffer_size.cast_unit()
+}
+
+#[inline]
+pub fn device_rect_as_framebuffer_rect(framebuffer_rect: &DeviceIntRect) -> FramebufferIntRect {
+ framebuffer_rect.cast_unit()
+}