From 2aa4a82499d4becd2284cdb482213d541b8804dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 16:29:10 +0200 Subject: Adding upstream version 86.0.1. Signed-off-by: Daniel Baumann --- gfx/wr/webrender_api/src/units.rs | 324 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 gfx/wr/webrender_api/src/units.rs (limited to 'gfx/wr/webrender_api/src/units.rs') diff --git a/gfx/wr/webrender_api/src/units.rs b/gfx/wr/webrender_api/src/units.rs new file mode 100644 index 0000000000..9913e4e664 --- /dev/null +++ b/gfx/wr/webrender_api/src/units.rs @@ -0,0 +1,324 @@ +/* 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 = Rect; +pub type DeviceIntPoint = Point2D; +pub type DeviceIntSize = Size2D; +pub type DeviceIntLength = Length; +pub type DeviceIntSideOffsets = SideOffsets2D; + +pub type DeviceRect = Rect; +pub type DevicePoint = Point2D; +pub type DeviceVector2D = Vector2D; +pub type DeviceSize = Size2D; +pub type DeviceHomogeneousVector = HomogeneousVector; + +/// 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; +pub type FramebufferIntSize = Size2D; +pub type FramebufferIntRect = Rect; + +/// 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 = Rect; +pub type PictureIntPoint = Point2D; +pub type PictureIntSize = Size2D; +pub type PictureRect = Rect; +pub type PicturePoint = Point2D; +pub type PictureSize = Size2D; +pub type PicturePoint3D = Point3D; +pub type PictureVector2D = Vector2D; +pub type PictureVector3D = Vector3D; +pub type PictureBox2D = Box2D; + +/// 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 = Rect; +pub type RasterIntPoint = Point2D; +pub type RasterIntSize = Size2D; +pub type RasterRect = Rect; +pub type RasterPoint = Point2D; +pub type RasterSize = Size2D; +pub type RasterPoint3D = Point3D; +pub type RasterVector2D = Vector2D; +pub type RasterVector3D = Vector3D; + +/// 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 = Rect; +pub type LayoutPoint = Point2D; +pub type LayoutPoint3D = Point3D; +pub type LayoutVector2D = Vector2D; +pub type LayoutVector3D = Vector3D; +pub type LayoutSize = Size2D; +pub type LayoutSideOffsets = SideOffsets2D; + +pub type LayoutIntRect = Rect; +pub type LayoutIntPoint = Point2D; +pub type LayoutIntSize = Size2D; + +/// Geometry in the document's coordinate space (logical pixels). +#[derive(Hash, Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Ord, PartialOrd)] +pub struct WorldPixel; + +pub type WorldRect = Rect; +pub type WorldPoint = Point2D; +pub type WorldSize = Size2D; +pub type WorldPoint3D = Point3D; +pub type WorldVector2D = Vector2D; +pub type WorldVector3D = Vector3D; + +/// Offset in number of tiles. +#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] +pub struct Tiles; +pub type TileOffset = Point2D; +pub type TileRange = Rect; + +/// Scaling ratio from world pixels to device pixels. +pub type DevicePixelScale = Scale; +/// 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; +/// A complete scaling ratio from layout space to device pixel space. +pub type LayoutToDeviceScale = Scale; + +pub type LayoutTransform = Transform3D; +pub type LayoutToWorldTransform = Transform3D; +pub type WorldToLayoutTransform = Transform3D; + +pub type LayoutToPictureTransform = Transform3D; +pub type PictureToLayoutTransform = Transform3D; + +pub type LayoutToRasterTransform = Transform3D; +pub type RasterToLayoutTransform = Transform3D; + +pub type PictureToRasterTransform = Transform3D; +pub type RasterToPictureTransform = Transform3D; + +// Fixed position coordinates, to avoid float precision errors. +pub type LayoutPointAu = Point2D; +pub type LayoutRectAu = Rect; +pub type LayoutSizeAu = Size2D; +pub type LayoutVector2DAu = Vector2D; +pub type LayoutSideOffsetsAu = SideOffsets2D; + +pub type ImageDirtyRect = DirtyRect; +pub type BlobDirtyRect = DirtyRect; + +pub type BlobToDeviceTranslation = Translation2D; + +/// 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, 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 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 { + fn from_au(data: T) -> Self; + fn to_au(&self) -> T; +} + +impl AuHelpers 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 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 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 for LayoutRect { + fn from_au(rect: LayoutRectAu) -> Self { + LayoutRect::new( + LayoutPoint::from_au(rect.origin), + LayoutSize::from_au(rect.size), + ) + } + + fn to_au(&self) -> LayoutRectAu { + LayoutRectAu::new( + self.origin.to_au(), + self.size.to_au(), + ) + } +} + +impl AuHelpers 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 RectExt for Rect { + type Point = Point2D; + 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() +} -- cgit v1.2.3