Bumping manifests a=b2g-bump
[gecko.git] / layout / svg / nsFilterInstance.h
blob9519912a7998ebe296bc5566be33ab4848846c49
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.
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.
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.
41 * The definition of "filter region" can be found here:
42 * http://www.w3.org/TR/SVG11/filters.html#FilterEffectsRegion
44 class nsFilterInstance
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).
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.
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.
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.
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.
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);
119 * Returns true if the filter instance was created successfully.
121 bool IsInitialized() const { return mInitialized; }
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.
129 nsresult Render(gfxContext* aContext);
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.
138 nsresult ComputePostFilterDirtyRegion(nsRegion* aPostFilterDirtyRegion);
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.
147 nsresult ComputePostFilterExtents(nsRect* aPostFilterExtents);
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.
156 nsresult ComputeSourceNeededRect(nsRect* aDirty);
160 * Returns the transform from filter space to outer-<svg> device space.
162 gfxMatrix GetFilterSpaceToDeviceSpaceTransform() const {
163 return mFilterSpaceToDeviceSpaceTransform;
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;
182 * Creates a SourceSurface for either the FillPaint or StrokePaint graph
183 * nodes
185 nsresult BuildSourcePaint(SourceInfo *aPrimitive,
186 DrawTarget* aTargetDT);
189 * Creates a SourceSurface for either the FillPaint and StrokePaint graph
190 * nodes, fills its contents and assigns it to mFillPaint.mSourceSurface and
191 * mStrokePaint.mSourceSurface respectively.
193 nsresult BuildSourcePaints(DrawTarget* aTargetDT);
196 * Creates the SourceSurface for the SourceGraphic graph node, paints its
197 * contents, and assigns it to mSourceGraphic.mSourceSurface.
199 nsresult BuildSourceImage(DrawTarget* aTargetDT);
202 * Build the list of FilterPrimitiveDescriptions that describes the filter's
203 * filter primitives and their connections. This populates
204 * mPrimitiveDescriptions and mInputImages.
206 nsresult BuildPrimitives();
209 * Add to the list of FilterPrimitiveDescriptions for a particular SVG
210 * reference filter or CSS filter. This populates mPrimitiveDescrs and
211 * mInputImages.
213 nsresult BuildPrimitivesForFilter(const nsStyleFilter& aFilter);
216 * Computes the filter space bounds of the areas that we actually *need* from
217 * the filter sources, based on the value of mPostFilterDirtyRegion.
218 * This sets mNeededBounds on the corresponding SourceInfo structs.
220 void ComputeNeededBoxes();
223 * Returns the output bounds of the final FilterPrimitiveDescription.
225 nsIntRect OutputFilterSpaceBounds() const;
228 * Compute the scale factors between user space and filter space.
230 nsresult ComputeUserSpaceToFilterSpaceScale();
233 * Transform a rect between user space and filter space.
235 gfxRect UserSpaceToFilterSpace(const gfxRect& aUserSpace) const;
236 gfxRect FilterSpaceToUserSpace(const gfxRect& aFilterSpaceRect) const;
239 * Converts an nsRect or an nsRegion that is relative to a filtered frame's
240 * origin (i.e. the top-left corner of its border box) into filter space,
241 * rounding out.
242 * Returns the entire filter region if aRect / aRegion is null, or if the
243 * result is too large to be stored in an nsIntRect.
245 nsIntRect FrameSpaceToFilterSpace(const nsRect* aRect) const;
246 nsIntRegion FrameSpaceToFilterSpace(const nsRegion* aRegion) const;
249 * Converts an nsIntRect or an nsIntRegion from filter space into the space
250 * that is relative to a filtered frame's origin (i.e. the top-left corner
251 * of its border box) in app units, rounding out.
253 nsRect FilterSpaceToFrameSpace(const nsIntRect& aRect) const;
254 nsRegion FilterSpaceToFrameSpace(const nsIntRegion& aRegion) const;
257 * Returns the transform from frame space to the coordinate space that
258 * GetCanvasTM transforms to. "Frame space" is the origin of a frame, aka the
259 * top-left corner of its border box, aka the top left corner of its mRect.
261 gfxMatrix GetUserSpaceToFrameSpaceInCSSPxTransform() const;
264 * The frame for the element that is currently being filtered.
266 nsIFrame* mTargetFrame;
268 nsSVGFilterPaintCallback* mPaintCallback;
271 * The SVG bbox of the element that is being filtered, in user space.
273 gfxRect mTargetBBox;
276 * The SVG bbox of the element that is being filtered, in filter space.
278 nsIntRect mTargetBBoxInFilterSpace;
281 * The transform from filter space to outer-<svg> device space.
283 gfxMatrix mFilterSpaceToDeviceSpaceTransform;
286 * Transform rects between filter space and frame space in CSS pixels.
288 gfxMatrix mFilterSpaceToFrameSpaceInCSSPxTransform;
289 gfxMatrix mFrameSpaceInCSSPxToFilterSpaceTransform;
292 * The scale factors between user space and filter space.
294 gfxSize mUserSpaceToFilterSpaceScale;
295 gfxSize mFilterSpaceToUserSpaceScale;
298 * Pre-filter paint bounds of the element that is being filtered, in filter
299 * space.
301 nsIntRect mTargetBounds;
304 * The dirty area that needs to be repainted, in filter space.
306 nsIntRegion mPostFilterDirtyRegion;
309 * The pre-filter area of the filtered element that changed, in filter space.
311 nsIntRegion mPreFilterDirtyRegion;
313 SourceInfo mSourceGraphic;
314 SourceInfo mFillPaint;
315 SourceInfo mStrokePaint;
316 nsIFrame* mTransformRoot;
317 nsTArray<mozilla::RefPtr<SourceSurface>> mInputImages;
318 nsTArray<FilterPrimitiveDescription> mPrimitiveDescriptions;
319 int32_t mAppUnitsPerCSSPx;
320 bool mInitialized;
323 #endif