layout/svg/nsFilterInstance.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: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     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 __NS_FILTERINSTANCE_H__
     7 #define __NS_FILTERINSTANCE_H__
     9 #include "gfxMatrix.h"
    10 #include "gfxPoint.h"
    11 #include "gfxRect.h"
    12 #include "nsCOMPtr.h"
    13 #include "nsHashKeys.h"
    14 #include "nsPoint.h"
    15 #include "nsRect.h"
    16 #include "nsSize.h"
    17 #include "nsSVGFilters.h"
    18 #include "nsSVGNumber2.h"
    19 #include "nsSVGNumberPair.h"
    20 #include "nsTArray.h"
    21 #include "nsIFrame.h"
    22 #include "mozilla/gfx/2D.h"
    24 class gfxASurface;
    25 class nsIFrame;
    26 class nsSVGFilterPaintCallback;
    28 /**
    29  * This class performs all filter processing.
    30  * 
    31  * We build a graph of the filter image data flow, essentially
    32  * converting the filter graph to SSA. This lets us easily propagate
    33  * analysis data (such as bounding-boxes) over the filter primitive graph.
    34  *
    35  * Definition of "filter space": filter space is a coordinate system that is
    36  * aligned with the user space of the filtered element, with its origin located
    37  * at the top left of the filter region, and with one unit equal in size to one
    38  * pixel of the offscreen surface into which the filter output would/will be
    39  * painted.
    40  *
    41  * The definition of "filter region" can be found here:
    42  * http://www.w3.org/TR/SVG11/filters.html#FilterEffectsRegion
    43  */
    44 class nsFilterInstance
    45 {
    46   typedef mozilla::gfx::IntRect IntRect;
    47   typedef mozilla::gfx::SourceSurface SourceSurface;
    48   typedef mozilla::gfx::DrawTarget DrawTarget;
    49   typedef mozilla::gfx::FilterPrimitiveDescription FilterPrimitiveDescription;
    51 public:
    52   /**
    53    * Paint the given filtered frame.
    54    * @param aDirtyArea The area than needs to be painted, in aFilteredFrame's
    55    *   frame space (i.e. relative to its origin, the top-left corner of its
    56    *   border box).
    57    */
    58   static nsresult PaintFilteredFrame(nsRenderingContext *aContext,
    59                                      nsIFrame *aFilteredFrame,
    60                                      nsSVGFilterPaintCallback *aPaintCallback,
    61                                      const nsRegion* aDirtyArea,
    62                                      nsIFrame* aTransformRoot = nullptr);
    64   /**
    65    * Returns the post-filter area that could be dirtied when the given
    66    * pre-filter area of aFilteredFrame changes.
    67    * @param aPreFilterDirtyRegion The pre-filter area of aFilteredFrame that has
    68    *   changed, relative to aFilteredFrame, in app units.
    69    */
    70   static nsRegion GetPostFilterDirtyArea(nsIFrame *aFilteredFrame,
    71                                          const nsRegion& aPreFilterDirtyRegion);
    73   /**
    74    * Returns the pre-filter area that is needed from aFilteredFrame when the
    75    * given post-filter area needs to be repainted.
    76    * @param aPostFilterDirtyRegion The post-filter area that is dirty, relative
    77    *   to aFilteredFrame, in app units.
    78    */
    79   static nsRegion GetPreFilterNeededArea(nsIFrame *aFilteredFrame,
    80                                          const nsRegion& aPostFilterDirtyRegion);
    82   /**
    83    * Returns the post-filter visual overflow rect (paint bounds) of
    84    * aFilteredFrame.
    85    * @param aOverrideBBox A user space rect, in user units, that should be used
    86    *   as aFilteredFrame's bbox ('bbox' is a specific SVG term), if non-null.
    87    * @param aPreFilterBounds The pre-filter visual overflow rect of
    88    *   aFilteredFrame, if non-null.
    89    */
    90   static nsRect GetPostFilterBounds(nsIFrame *aFilteredFrame,
    91                                     const gfxRect *aOverrideBBox = nullptr,
    92                                     const nsRect *aPreFilterBounds = nullptr);
    94   /**
    95    * @param aTargetFrame The frame of the filtered element under consideration.
    96    * @param aPaintCallback [optional] The callback that Render() should use to
    97    *   paint. Only required if you will call Render().
    98    * @param aPostFilterDirtyRegion [optional] The post-filter area
    99    *   that has to be repainted, in app units. Only required if you will
   100    *   call ComputeSourceNeededRect() or Render().
   101    * @param aPreFilterDirtyRegion [optional] The pre-filter area of
   102    *   the filtered element that changed, in app units. Only required if you
   103    *   will call ComputePostFilterDirtyRegion().
   104    * @param aOverridePreFilterVisualOverflowRect [optional] Use a different
   105    *   visual overflow rect for the target element.
   106    * @param aOverrideBBox [optional] Use a different SVG bbox for the target
   107    *   element.
   108    * @param aTransformRoot [optional] The transform root frame for painting.
   109    */
   110   nsFilterInstance(nsIFrame *aTargetFrame,
   111                    nsSVGFilterPaintCallback *aPaintCallback,
   112                    const nsRegion *aPostFilterDirtyRegion = nullptr,
   113                    const nsRegion *aPreFilterDirtyRegion = nullptr,
   114                    const nsRect *aOverridePreFilterVisualOverflowRect = nullptr,
   115                    const gfxRect *aOverrideBBox = nullptr,
   116                    nsIFrame* aTransformRoot = nullptr);
   118   /**
   119    * Returns true if the filter instance was created successfully.
   120    */
   121   bool IsInitialized() const { return mInitialized; }
   123   /**
   124    * Draws the filter output into aContext. The area that
   125    * needs to be painted must have been specified before calling this method
   126    * by passing it as the aPostFilterDirtyRegion argument to the
   127    * nsFilterInstance constructor.
   128    */
   129   nsresult Render(gfxContext* aContext);
   131   /**
   132    * Sets the aPostFilterDirtyRegion outparam to the post-filter area in frame
   133    * space that would be dirtied by mTargetFrame when a given
   134    * pre-filter area of mTargetFrame is dirtied. The pre-filter area must have
   135    * been specified before calling this method by passing it as the
   136    * aPreFilterDirtyRegion argument to the nsFilterInstance constructor.
   137    */
   138   nsresult ComputePostFilterDirtyRegion(nsRegion* aPostFilterDirtyRegion);
   140   /**
   141    * Sets the aPostFilterExtents outparam to the post-filter bounds in frame
   142    * space for the whole filter output. This is not necessarily equivalent to
   143    * the area that would be dirtied in the result when the entire pre-filter
   144    * area is dirtied, because some filter primitives can generate output
   145    * without any input.
   146    */
   147   nsresult ComputePostFilterExtents(nsRect* aPostFilterExtents);
   149   /**
   150    * Sets the aDirty outparam to the pre-filter bounds in frame space of the
   151    * area of mTargetFrame that is needed in order to paint the filtered output
   152    * for a given post-filter dirtied area. The post-filter area must have been
   153    * specified before calling this method by passing it as the aPostFilterDirtyRegion
   154    * argument to the nsFilterInstance constructor.
   155    */
   156   nsresult ComputeSourceNeededRect(nsRect* aDirty);
   159   /**
   160    * Returns the transform from filter space to outer-<svg> device space.
   161    */
   162   gfxMatrix GetFilterSpaceToDeviceSpaceTransform() const {
   163     return mFilterSpaceToDeviceSpaceTransform;
   164   }
   166 private:
   167   struct SourceInfo {
   168     // Specifies which parts of the source need to be rendered.
   169     // Set by ComputeNeededBoxes().
   170     nsIntRect mNeededBounds;
   172     // The surface that contains the input rendering.
   173     // Set by BuildSourceImage / BuildSourcePaint.
   174     mozilla::RefPtr<SourceSurface> mSourceSurface;
   176     // The position and size of mSourceSurface in filter space.
   177     // Set by BuildSourceImage / BuildSourcePaint.
   178     IntRect mSurfaceRect;
   179   };
   181   /**
   182    * Creates a SourceSurface for either the FillPaint or StrokePaint graph
   183    * nodes
   184    */
   185   nsresult BuildSourcePaint(SourceInfo *aPrimitive,
   186                             gfxASurface* aTargetSurface,
   187                             DrawTarget* aTargetDT);
   189   /**
   190    * Creates a SourceSurface for either the FillPaint and StrokePaint graph
   191    * nodes, fills its contents and assigns it to mFillPaint.mSourceSurface and
   192    * mStrokePaint.mSourceSurface respectively.
   193    */
   194   nsresult BuildSourcePaints(gfxASurface* aTargetSurface,
   195                              DrawTarget* aTargetDT);
   197   /**
   198    * Creates the SourceSurface for the SourceGraphic graph node, paints its
   199    * contents, and assigns it to mSourceGraphic.mSourceSurface.
   200    */
   201   nsresult BuildSourceImage(gfxASurface* aTargetSurface,
   202                             DrawTarget* aTargetDT);
   204   /**
   205    * Build the list of FilterPrimitiveDescriptions that describes the filter's
   206    * filter primitives and their connections. This populates
   207    * mPrimitiveDescriptions and mInputImages.
   208    */
   209   nsresult BuildPrimitives();
   211   /**
   212    * Add to the list of FilterPrimitiveDescriptions for a particular SVG
   213    * reference filter or CSS filter. This populates mPrimitiveDescrs and
   214    * mInputImages.
   215    */
   216   nsresult BuildPrimitivesForFilter(const nsStyleFilter& aFilter);
   218   /**
   219    * Computes the filter space bounds of the areas that we actually *need* from
   220    * the filter sources, based on the value of mPostFilterDirtyRegion.
   221    * This sets mNeededBounds on the corresponding SourceInfo structs.
   222    */
   223   void ComputeNeededBoxes();
   225   /**
   226    * Compute the scale factors between user space and filter space.
   227    */
   228   nsresult ComputeUserSpaceToFilterSpaceScale();
   230   /**
   231    * Transform a rect between user space and filter space.
   232    */
   233   gfxRect UserSpaceToFilterSpace(const gfxRect& aUserSpace) const;
   234   gfxRect FilterSpaceToUserSpace(const gfxRect& aFilterSpaceRect) const;
   236   /**
   237    * Converts an nsRect or an nsRegion that is relative to a filtered frame's
   238    * origin (i.e. the top-left corner of its border box) into filter space,
   239    * rounding out.
   240    * Returns the entire filter region if aRect / aRegion is null, or if the
   241    * result is too large to be stored in an nsIntRect.
   242    */
   243   nsIntRect FrameSpaceToFilterSpace(const nsRect* aRect) const;
   244   nsIntRegion FrameSpaceToFilterSpace(const nsRegion* aRegion) const;
   246   /**
   247    * Converts an nsIntRect or an nsIntRegion from filter space into the space
   248    * that is relative to a filtered frame's origin (i.e. the top-left corner
   249    * of its border box) in app units, rounding out.
   250    */
   251   nsRect FilterSpaceToFrameSpace(const nsIntRect& aRect) const;
   252   nsRegion FilterSpaceToFrameSpace(const nsIntRegion& aRegion) const;
   254   /**
   255    * Returns the transform from frame space to the coordinate space that
   256    * GetCanvasTM transforms to. "Frame space" is the origin of a frame, aka the
   257    * top-left corner of its border box, aka the top left corner of its mRect.
   258    */
   259   gfxMatrix GetUserSpaceToFrameSpaceInCSSPxTransform() const;
   261   /**
   262    * The frame for the element that is currently being filtered.
   263    */
   264   nsIFrame*               mTargetFrame;
   266   nsSVGFilterPaintCallback* mPaintCallback;
   268   /**
   269    * The SVG bbox of the element that is being filtered, in user space.
   270    */
   271   gfxRect                 mTargetBBox;
   273   /**
   274    * The transform from filter space to outer-<svg> device space.
   275    */
   276   gfxMatrix               mFilterSpaceToDeviceSpaceTransform;
   278   /**
   279    * Transform rects between filter space and frame space in CSS pixels.
   280    */
   281   gfxMatrix               mFilterSpaceToFrameSpaceInCSSPxTransform;
   282   gfxMatrix               mFrameSpaceInCSSPxToFilterSpaceTransform;
   284   /**
   285    * The "filter region", in the filtered element's user space.
   286    */
   287   gfxRect                 mUserSpaceBounds;
   288   nsIntRect               mFilterSpaceBounds;
   290   /**
   291    * The scale factors between user space and filter space.
   292    */
   293   gfxSize                 mUserSpaceToFilterSpaceScale;
   294   gfxSize                 mFilterSpaceToUserSpaceScale;
   296   /**
   297    * Pre-filter paint bounds of the element that is being filtered, in filter
   298    * space.
   299    */
   300   nsIntRect               mTargetBounds;
   302   /**
   303    * The dirty area that needs to be repainted, in filter space.
   304    */
   305   nsIntRegion             mPostFilterDirtyRegion;
   307   /**
   308    * The pre-filter area of the filtered element that changed, in filter space.
   309    */
   310   nsIntRegion             mPreFilterDirtyRegion;
   312   SourceInfo              mSourceGraphic;
   313   SourceInfo              mFillPaint;
   314   SourceInfo              mStrokePaint;
   315   nsIFrame*               mTransformRoot;
   316   nsTArray<mozilla::RefPtr<SourceSurface>> mInputImages;
   317   nsTArray<FilterPrimitiveDescription> mPrimitiveDescriptions;
   318   int32_t                 mAppUnitsPerCSSPx;
   319   bool                    mInitialized;
   320 };
   322 #endif

mercurial