gfx/thebes/gfx3DMatrix.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef GFX_3DMATRIX_H
     7 #define GFX_3DMATRIX_H
     9 #include <gfxTypes.h>
    10 #include <gfxPoint3D.h>
    11 #include <gfxPointH3D.h>
    12 #include <gfxQuad.h>
    14 struct gfxMatrix;
    16 /**
    17  * This class represents a 3D transformation. The matrix is laid
    18  * out as follows:
    19  *
    20  * _11 _12 _13 _14
    21  * _21 _22 _23 _24
    22  * _31 _32 _33 _34
    23  * _41 _42 _43 _44
    24  *
    25  * This matrix is treated as row-major. Assuming we consider our vectors row
    26  * vectors, this matrix type will be identical in memory to the OpenGL and D3D
    27  * matrices. OpenGL matrices are column-major, however OpenGL also treats
    28  * vectors as column vectors, the double transposition makes everything work
    29  * out nicely.
    30  */
    31 class gfx3DMatrix
    32 {
    33 public:
    34   /**
    35    * Create matrix.
    36    */
    37   gfx3DMatrix(void);
    39   /**
    40    * Matrix multiplication.
    41    */
    42   gfx3DMatrix operator*(const gfx3DMatrix &aMatrix) const;
    43   gfx3DMatrix& operator*=(const gfx3DMatrix &aMatrix);
    45   gfxPointH3D& operator[](int aIndex)
    46   {
    47       NS_ABORT_IF_FALSE(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index");
    48       return *reinterpret_cast<gfxPointH3D*>((&_11)+4*aIndex);
    49   }
    50   const gfxPointH3D& operator[](int aIndex) const
    51   {
    52       NS_ABORT_IF_FALSE(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index");
    53       return *reinterpret_cast<const gfxPointH3D*>((&_11)+4*aIndex);
    54   }
    56   /**
    57    * Return true if this matrix and |aMatrix| are the same matrix.
    58    */
    59   bool operator==(const gfx3DMatrix& aMatrix) const;
    60   bool operator!=(const gfx3DMatrix& aMatrix) const;
    62   bool FuzzyEqual(const gfx3DMatrix& aMatrix) const;
    64   /**
    65    * Divide all values in the matrix by a scalar value
    66    */
    67   gfx3DMatrix& operator/=(gfxFloat scalar);
    69   /**
    70    * Create a 3D matrix from a gfxMatrix 2D affine transformation.
    71    *
    72    * \param aMatrix gfxMatrix 2D affine transformation.
    73    */
    74   static gfx3DMatrix From2D(const gfxMatrix &aMatrix);
    76   /**
    77    * Returns true if the matrix is isomorphic to a 2D affine transformation
    78    * (i.e. as obtained by From2D). If it is, optionally returns the 2D
    79    * matrix in aMatrix.
    80    */
    81   bool Is2D(gfxMatrix* aMatrix) const;
    82   bool Is2D() const;
    84   /**
    85    * Returns true if the matrix can be reduced to a 2D affine transformation
    86    * (i.e. as obtained by From2D). If it is, optionally returns the 2D
    87    * matrix in aMatrix. This should only be used on matrices required for
    88    * rendering, not for intermediate calculations. It is assumed that the 2D
    89    * matrix will only be used for transforming objects on to the z=0 plane,
    90    * therefore any z-component perspective is ignored. This means that if
    91    * aMatrix is applied to objects with z != 0, the results may be incorrect.
    92    *
    93    * Since drawing is to a 2d plane, any 3d transform without perspective
    94    * can be reduced by dropping the z row and column.
    95    */
    96   bool CanDraw2D(gfxMatrix* aMatrix = nullptr) const;
    98   /**
    99    * Converts the matrix to one that doesn't modify the z coordinate of points,
   100    * but leaves the rest of the transformation unchanged.
   101    */
   102   gfx3DMatrix& ProjectTo2D();
   104   /**
   105    * Returns true if the matrix is the identity matrix. The most important
   106    * property we require is that gfx3DMatrix().IsIdentity() returns true.
   107    */
   108   bool IsIdentity() const;
   110   /**
   111    * Pre-multiplication transformation functions:
   112    *
   113    * These functions construct a temporary matrix containing
   114    * a single transformation and pre-multiply it onto the current
   115    * matrix.
   116    */
   118   /**
   119    * Add a translation by aPoint to the matrix.
   120    *
   121    * This creates this temporary matrix:
   122    * |  1        0        0         0 |
   123    * |  0        1        0         0 |
   124    * |  0        0        1         0 |
   125    * |  aPoint.x aPoint.y aPoint.z  1 |
   126    */
   127   void Translate(const gfxPoint3D& aPoint);
   129   /** 
   130    * Skew the matrix.
   131    *
   132    * This creates this temporary matrix:
   133    * | 1           tan(aYSkew) 0 0 |
   134    * | tan(aXSkew) 1           0 0 |
   135    * | 0           0           1 0 |
   136    * | 0           0           0 1 |
   137    */
   138   void SkewXY(double aXSkew, double aYSkew);
   140   void SkewXY(double aSkew);
   141   void SkewXZ(double aSkew);
   142   void SkewYZ(double aSkew);
   144   /**
   145    * Scale the matrix
   146    *
   147    * This creates this temporary matrix:
   148    * | aX 0  0  0 |
   149    * | 0  aY 0  0 |
   150    * | 0  0  aZ 0 |
   151    * | 0  0  0  1 |
   152    */
   153   void Scale(float aX, float aY, float aZ);
   155   /**
   156    * Return the currently set scaling factors.
   157    */
   158   float GetXScale() const { return _11; }
   159   float GetYScale() const { return _22; }
   160   float GetZScale() const { return _33; }
   162   /**
   163    * Rotate around the X axis..
   164    *
   165    * This creates this temporary matrix:
   166    * | 1 0            0           0 |
   167    * | 0 cos(aTheta)  sin(aTheta) 0 |
   168    * | 0 -sin(aTheta) cos(aTheta) 0 |
   169    * | 0 0            0           1 |
   170    */
   171   void RotateX(double aTheta);
   173   /**
   174    * Rotate around the Y axis..
   175    *
   176    * This creates this temporary matrix:
   177    * | cos(aTheta) 0 -sin(aTheta) 0 |
   178    * | 0           1 0            0 |
   179    * | sin(aTheta) 0 cos(aTheta)  0 |
   180    * | 0           0 0            1 |
   181    */
   182   void RotateY(double aTheta);
   184   /**
   185    * Rotate around the Z axis..
   186    *
   187    * This creates this temporary matrix:
   188    * | cos(aTheta)  sin(aTheta)  0 0 |
   189    * | -sin(aTheta) cos(aTheta)  0 0 |
   190    * | 0            0            1 0 |
   191    * | 0            0            0 1 |
   192    */
   193   void RotateZ(double aTheta);
   195   /**
   196    * Apply perspective to the matrix.
   197    *
   198    * This creates this temporary matrix:
   199    * | 1 0 0 0         |
   200    * | 0 1 0 0         |
   201    * | 0 0 1 -1/aDepth |
   202    * | 0 0 0 1         |
   203    */
   204   void Perspective(float aDepth);
   206   /**
   207    * Pre multiply an existing matrix onto the current
   208    * matrix
   209    */
   210   void PreMultiply(const gfx3DMatrix& aOther);
   211   void PreMultiply(const gfxMatrix& aOther);
   213   /**
   214    * Post-multiplication transformation functions:
   215    *
   216    * These functions construct a temporary matrix containing
   217    * a single transformation and post-multiply it onto the current
   218    * matrix.
   219    */
   221   /**
   222    * Add a translation by aPoint after the matrix.
   223    * This is functionally equivalent to:
   224    * matrix * gfx3DMatrix::Translation(aPoint)
   225    */
   226   void TranslatePost(const gfxPoint3D& aPoint);
   228   void ScalePost(float aX, float aY, float aZ);
   230   /**
   231    * Transforms a point according to this matrix.
   232    */
   233   gfxPoint Transform(const gfxPoint& point) const;
   235   /**
   236    * Transforms a rectangle according to this matrix
   237    */
   238   gfxRect TransformBounds(const gfxRect& rect) const;
   241   gfxQuad TransformRect(const gfxRect& aRect) const;
   243   /** 
   244    * Transforms a 3D vector according to this matrix.
   245    */
   246   gfxPoint3D Transform3D(const gfxPoint3D& point) const;
   247   gfxPointH3D Transform4D(const gfxPointH3D& aPoint) const;
   248   gfxPointH3D TransposeTransform4D(const gfxPointH3D& aPoint) const;
   250   gfxPoint ProjectPoint(const gfxPoint& aPoint) const;
   251   gfxRect ProjectRectBounds(const gfxRect& aRect) const;
   253   /**
   254    * Transforms a point by the inverse of this matrix. In the case of perspective transforms, some screen
   255    * points have no equivalent in the untransformed plane (if they exist past the vanishing point). To
   256    * avoid this, we need to specify the bounds of the untransformed plane to restrict the search area.
   257    *
   258    * @param aPoint Point to untransform.
   259    * @param aChildBounds Bounds of the untransformed plane.
   260    * @param aOut Untransformed point.
   261    * @return Returns true if a point was found within a ChildBounds, false otherwise.
   262    */
   263   bool UntransformPoint(const gfxPoint& aPoint, const gfxRect& aChildBounds, gfxPoint* aOut) const;
   266   /**
   267    * Same as UntransformPoint, but untransforms a rect and returns the bounding rect of the result.
   268    * Returns an empty rect if the result doesn't intersect aChildBounds.
   269    */
   270   gfxRect UntransformBounds(const gfxRect& aRect, const gfxRect& aChildBounds) const;
   273   /**
   274    * Inverts this matrix, if possible. Otherwise, the matrix is left
   275    * unchanged.
   276    */
   277   gfx3DMatrix Inverse() const;
   279   gfx3DMatrix& Invert()
   280   {
   281       *this = Inverse();
   282       return *this;
   283   }
   285   gfx3DMatrix& Normalize();
   287   gfxPointH3D TransposedVector(int aIndex) const
   288   {
   289       NS_ABORT_IF_FALSE(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index");
   290       return gfxPointH3D(*((&_11)+aIndex), *((&_21)+aIndex), *((&_31)+aIndex), *((&_41)+aIndex));
   291   }
   293   void SetTransposedVector(int aIndex, gfxPointH3D &aVector)
   294   {
   295       NS_ABORT_IF_FALSE(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index");
   296       *((&_11)+aIndex) = aVector.x;
   297       *((&_21)+aIndex) = aVector.y;
   298       *((&_31)+aIndex) = aVector.z;
   299       *((&_41)+aIndex) = aVector.w;
   300   }
   302   gfx3DMatrix& Transpose();
   303   gfx3DMatrix Transposed() const;
   305   /**
   306    * Returns a unit vector that is perpendicular to the plane formed
   307    * by transform the screen plane (z=0) by this matrix.
   308    */
   309   gfxPoint3D GetNormalVector() const;
   311   /**
   312    * Returns true if a plane transformed by this matrix will
   313    * have it's back face visible.
   314    */
   315   bool IsBackfaceVisible() const;
   317   /**
   318    * Check if matrix is singular (no inverse exists).
   319    */
   320   bool IsSingular() const;
   322   /**
   323    * Create a translation matrix.
   324    *
   325    * \param aX Translation on X-axis.
   326    * \param aY Translation on Y-axis.
   327    * \param aZ Translation on Z-axis.
   328    */
   329   static gfx3DMatrix Translation(float aX, float aY, float aZ);
   330   static gfx3DMatrix Translation(const gfxPoint3D& aPoint);
   332   /**
   333    * Create a scale matrix. Scales uniformly along all axes.
   334    *
   335    * \param aScale Scale factor
   336    */
   337   static gfx3DMatrix ScalingMatrix(float aFactor);
   339   /**
   340    * Create a scale matrix.
   341    */
   342   static gfx3DMatrix ScalingMatrix(float aX, float aY, float aZ);
   344   gfxFloat Determinant() const;
   346   void NudgeToIntegers(void);
   348 private:
   350   gfxFloat Determinant3x3() const;
   351   gfx3DMatrix Inverse3x3() const;
   353   gfx3DMatrix Multiply2D(const gfx3DMatrix &aMatrix) const;
   355 public:
   357   /** Matrix elements */
   358   float _11, _12, _13, _14;
   359   float _21, _22, _23, _24;
   360   float _31, _32, _33, _34;
   361   float _41, _42, _43, _44;
   362 };
   364 #endif /* GFX_3DMATRIX_H */

mercurial