mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 05:45:37 +00:00
Bug 745066 - Add comments documenting the declaration of nsSVGFilterInstance, its methods and its members. r=longsonr.
This commit is contained in:
parent
3038face63
commit
e0223efe12
@ -100,7 +100,7 @@ public:
|
||||
const nsIntRect *aDirtyOutputRect,
|
||||
const nsIntRect *aDirtyInputRect,
|
||||
const nsIntRect *aOverrideSourceBBox);
|
||||
~nsAutoFilterInstance();
|
||||
~nsAutoFilterInstance() {}
|
||||
|
||||
// If this returns null, then draw nothing. Either the filter draws
|
||||
// nothing or it is "in error".
|
||||
@ -108,9 +108,6 @@ public:
|
||||
|
||||
private:
|
||||
nsAutoPtr<nsSVGFilterInstance> mInstance;
|
||||
// Store mTarget separately even though mInstance has it, because if
|
||||
// mInstance creation fails we still need to be able to clean up
|
||||
nsISVGChildFrame* mTarget;
|
||||
};
|
||||
|
||||
nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
|
||||
@ -120,8 +117,6 @@ nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
|
||||
const nsIntRect *aDirtyInputRect,
|
||||
const nsIntRect *aOverrideSourceBBox)
|
||||
{
|
||||
mTarget = do_QueryFrame(aTarget);
|
||||
|
||||
const nsSVGFilterElement *filter = aFilterFrame->GetFilterContent();
|
||||
|
||||
PRUint16 filterUnits =
|
||||
@ -247,10 +242,6 @@ nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
|
||||
primitiveUnits);
|
||||
}
|
||||
|
||||
nsAutoFilterInstance::~nsAutoFilterInstance()
|
||||
{
|
||||
}
|
||||
|
||||
PRUint16
|
||||
nsSVGFilterFrame::GetEnumValue(PRUint32 aIndex, nsIContent *aDefault)
|
||||
{
|
||||
|
@ -62,10 +62,42 @@ class nsSVGFilterPaintCallback;
|
||||
* We build a graph of the filter image data flow, essentially
|
||||
* converting the filter graph to SSA. This lets us easily propagate
|
||||
* analysis data (such as bounding-boxes) over the filter primitive graph.
|
||||
*
|
||||
* Definition of "filter space": filter space is a coordinate system that is
|
||||
* aligned with the user space of the filtered element, with its origin located
|
||||
* at the top left of the filter region (as returned by GetFilterRect,
|
||||
* specifically), and with one unit equal in size to one pixel of the offscreen
|
||||
* surface into which the filter output would/will be painted.
|
||||
*/
|
||||
class NS_STACK_CLASS nsSVGFilterInstance
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param aTargetFrame The frame of the filtered element under consideration.
|
||||
* @param aPaintCallback [optional] The callback that Render() should use to
|
||||
* paint. Only required if you will call Render().
|
||||
* @param aFilterElement The filter element referenced by aTargetFrame's
|
||||
* element.
|
||||
* @param aTargetBBox The filtered element's bbox, in the filtered element's
|
||||
* user space.
|
||||
* @param aFilterRect The "filter region", in the filtered element's user
|
||||
* space. The caller must have already expanded the region out so that its
|
||||
* edges coincide with pixel boundaries in the offscreen surface that
|
||||
* would/will be created to paint the filter output.
|
||||
* @param aFilterSpaceSize The size of the user specified "filter region",
|
||||
* in filter space units.
|
||||
* @param aFilterSpaceToDeviceSpaceTransform The transform from filter
|
||||
* space to outer-<svg> device space.
|
||||
* @param aTargetBounds The pre-filter paint bounds of the filtered element,
|
||||
* in filter space.
|
||||
* @param aDirtyOutputRect [optional] The bounds of the post-filter area that
|
||||
* has to be repainted, in filter space. Only required if you will call
|
||||
* ComputeSourceNeededRect() or Render().
|
||||
* @param aDirtyInputRect [optional] The bounds of the pre-filter area of the
|
||||
* filtered element that changed, in filter space. Only required if you
|
||||
* will call ComputeOutputDirtyRect().
|
||||
* @param aPrimitiveUnits The value from the 'primitiveUnits' attribute.
|
||||
*/
|
||||
nsSVGFilterInstance(nsIFrame *aTargetFrame,
|
||||
nsSVGFilterPaintCallback *aPaintCallback,
|
||||
const nsSVGFilterElement *aFilterElement,
|
||||
@ -84,29 +116,75 @@ public:
|
||||
mFilterSpaceToDeviceSpaceTransform(aFilterSpaceToDeviceSpaceTransform),
|
||||
mFilterRect(aFilterRect),
|
||||
mFilterSpaceSize(aFilterSpaceSize),
|
||||
mSurfaceRect(nsIntPoint(0, 0), aFilterSpaceSize),
|
||||
mTargetBounds(aTargetBounds),
|
||||
mDirtyOutputRect(aDirtyOutputRect),
|
||||
mDirtyInputRect(aDirtyInputRect),
|
||||
mSurfaceRect(nsIntPoint(0, 0), aFilterSpaceSize),
|
||||
mPrimitiveUnits(aPrimitiveUnits) {
|
||||
}
|
||||
|
||||
// The area covered by temporary images, in filter space
|
||||
void SetSurfaceRect(const nsIntRect& aRect) { mSurfaceRect = aRect; }
|
||||
|
||||
/**
|
||||
* Returns the user specified "filter region", in the filtered element's user
|
||||
* space, after it has been adjusted out (if necessary) so that its edges
|
||||
* coincide with pixel boundaries of the offscreen surface into which the
|
||||
* filtered output would/will be painted.
|
||||
*/
|
||||
gfxRect GetFilterRect() const { return mFilterRect; }
|
||||
|
||||
/**
|
||||
* Returns the size of the user specified "filter region", in filter space.
|
||||
* The size will be {filterRes.x by filterRes.y}, whether the user specified
|
||||
* the filter's filterRes attribute explicitly, or the implementation chose
|
||||
* the filterRes values. (The top-left of the filter region is the origin of
|
||||
* filter space, which is why this method returns an nsIntSize and not an
|
||||
* nsIntRect.)
|
||||
*/
|
||||
const nsIntSize& GetFilterSpaceSize() { return mFilterSpaceSize; }
|
||||
PRUint32 GetFilterResX() const { return mFilterSpaceSize.width; }
|
||||
PRUint32 GetFilterResY() const { return mFilterSpaceSize.height; }
|
||||
|
||||
|
||||
/**
|
||||
* Returns the dimensions of the offscreen surface that is required for the
|
||||
* output from the current filter operation, in filter space. This rect is
|
||||
* clipped to, and therefore guaranteed to be fully contained by, the filter
|
||||
* region.
|
||||
*/
|
||||
const nsIntRect& GetSurfaceRect() const { return mSurfaceRect; }
|
||||
PRInt32 GetSurfaceWidth() const { return mSurfaceRect.width; }
|
||||
PRInt32 GetSurfaceHeight() const { return mSurfaceRect.height; }
|
||||
|
||||
|
||||
/**
|
||||
* Allocates a gfxASurface, renders the filtered element into the surface,
|
||||
* and then returns the surface via the aOutput outparam. The area that
|
||||
* needs to be painted must have been specified before calling this method
|
||||
* by passing it as the aDirtyOutputRect argument to the
|
||||
* nsSVGFilterInstance constructor.
|
||||
*/
|
||||
nsresult Render(gfxASurface** aOutput);
|
||||
|
||||
/**
|
||||
* Sets the aDirty outparam to the post-filter bounds in filter space of the
|
||||
* area that would be dirtied by mTargetFrame when a given pre-filter area of
|
||||
* mTargetFrame is dirtied. The pre-filter area must have been specified
|
||||
* before calling this method by passing it as the aDirtyInputRect argument
|
||||
* to the nsSVGFilterInstance constructor.
|
||||
*/
|
||||
nsresult ComputeOutputDirtyRect(nsIntRect* aDirty);
|
||||
|
||||
/**
|
||||
* Sets the aDirty outparam to the pre-filter bounds in filter space of the
|
||||
* area of mTargetFrame that is needed in order to paint the filtered output
|
||||
* for a given post-filter dirtied area. The post-filter area must have been
|
||||
* specified before calling this method by passing it as the aDirtyOutputRect
|
||||
* argument to the nsSVGFilterInstance constructor.
|
||||
*/
|
||||
nsresult ComputeSourceNeededRect(nsIntRect* aDirty);
|
||||
|
||||
/**
|
||||
* Sets the aDirty outparam to the post-filter bounds in filter space of the
|
||||
* area that would be dirtied by mTargetFrame if its entire pre-filter area
|
||||
* is dirtied.
|
||||
*/
|
||||
nsresult ComputeOutputBBox(nsIntRect* aBBox);
|
||||
|
||||
float GetPrimitiveNumber(PRUint8 aCtxType, const nsSVGNumber2 *aNumber) const
|
||||
@ -118,17 +196,27 @@ public:
|
||||
{
|
||||
return GetPrimitiveNumber(aCtxType, aNumberPair->GetAnimValue(aIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a point and a length in filter primitive units into filter space.
|
||||
* For object-bounding-box units, the object bounding box offset is applied
|
||||
* to the point.
|
||||
* Converts a userSpaceOnUse/objectBoundingBoxUnits unitless point and length
|
||||
* into filter space, depending on the value of mPrimitiveUnits. (For
|
||||
* objectBoundingBoxUnits, the bounding box offset is applied to the point.)
|
||||
*/
|
||||
void ConvertLocation(float aValues[3]) const;
|
||||
|
||||
/**
|
||||
* Returns the transform from the filtered element's user space to filter
|
||||
* space. This will be a simple translation and/or scale.
|
||||
*/
|
||||
gfxMatrix GetUserSpaceToFilterSpaceTransform() const;
|
||||
|
||||
/**
|
||||
* Returns the transform from filter space to outer-<svg> device space.
|
||||
*/
|
||||
gfxMatrix GetFilterSpaceToDeviceSpaceTransform() const {
|
||||
return mFilterSpaceToDeviceSpaceTransform;
|
||||
}
|
||||
|
||||
gfxPoint FilterSpaceToUserSpace(const gfxPoint& aPt) const;
|
||||
|
||||
private:
|
||||
@ -136,19 +224,50 @@ private:
|
||||
typedef nsSVGFE::ColorModel ColorModel;
|
||||
|
||||
struct PrimitiveInfo {
|
||||
/// Pointer to the filter primitive element.
|
||||
nsSVGFE* mFE;
|
||||
// the bounding box of the result image produced by this primitive, in
|
||||
// filter space
|
||||
|
||||
/**
|
||||
* The filter space bounds of this filter primitive's output, were a full
|
||||
* repaint of mTargetFrame to occur. Note that a filter primitive's output
|
||||
* (and hence this rect) is always clipped to both the filter region and
|
||||
* to the filter primitive subregion.
|
||||
* XXX maybe rename this to mMaxBounds?
|
||||
*/
|
||||
nsIntRect mResultBoundingBox;
|
||||
// the bounding box of the part of the result image that is actually
|
||||
// needed by other primitives or by the filter result, in filter space
|
||||
// (used for Render only)
|
||||
|
||||
/**
|
||||
* The filter space bounds of this filter primitive's output, were we to
|
||||
* repaint a given post-filter dirty area, and were we to minimize
|
||||
* repainting for that dirty area. In other words this is the part of the
|
||||
* primitive's output that is needed by other primitives or the final
|
||||
* filtered output in order to repaint that area. This rect is guaranteed
|
||||
* to be contained within mResultBoundingBox and, if we're only painting
|
||||
* part of the filtered output, may be smaller. This rect is used when
|
||||
* calling Render() or ComputeSourceNeededRect().
|
||||
* XXX maybe rename this to just mNeededBounds?
|
||||
*/
|
||||
nsIntRect mResultNeededBox;
|
||||
// the bounding box of the part of the result image that could be
|
||||
// changed by changes to mDirtyInputRect in the source image(s)
|
||||
// (used for ComputeOutputDirtyRect only)
|
||||
|
||||
/**
|
||||
* The filter space bounds of this filter primitive's output, were only
|
||||
* part of mTargetFrame's pre-filter output to be dirtied, and were we to
|
||||
* minimize repainting for that dirty area. This is used when calculating
|
||||
* the area that needs to be invalidated when only part of a filtered
|
||||
* element is dirtied. This rect is guaranteed to be contained within
|
||||
* mResultBoundingBox.
|
||||
*/
|
||||
nsIntRect mResultChangeBox;
|
||||
|
||||
Image mImage;
|
||||
|
||||
/**
|
||||
* The number of times that this filter primitive's output is used as an
|
||||
* input by other filter primitives in the filter graph.
|
||||
* XXX seems like we could better use this to avoid creating images for
|
||||
* primitives that are not used, or whose ouput in not used during the
|
||||
* current operation.
|
||||
*/
|
||||
PRInt32 mImageUsers;
|
||||
|
||||
// Can't use nsAutoTArray here, because these Info objects
|
||||
@ -168,27 +287,76 @@ private:
|
||||
PrimitiveInfo* mInfo;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the SourceGraphic and SourceAlpha graph nodes (i.e. sets
|
||||
* .mImage.mFilterPrimitiveSubregion and .mResultBoundingBox on
|
||||
* mSourceColorAlpha and mSourceAlpha).
|
||||
*/
|
||||
nsresult BuildSources();
|
||||
// Build graph of PrimitiveInfo nodes describing filter primitives
|
||||
nsresult BuildPrimitives();
|
||||
// Compute bounding boxes of the filter primitive outputs
|
||||
void ComputeResultBoundingBoxes();
|
||||
// Compute bounding boxes of what we actually *need* from the filter
|
||||
// primitive outputs
|
||||
void ComputeNeededBoxes();
|
||||
// Compute bounding boxes of what could have changed given some changes
|
||||
// to the source images.
|
||||
void ComputeResultChangeBoxes();
|
||||
nsIntRect ComputeUnionOfAllNeededBoxes();
|
||||
|
||||
/**
|
||||
* Creates the gfxImageSurfaces for the SourceGraphic and SourceAlpha graph
|
||||
* nodes, paints their contents, and assigns them to
|
||||
* mSourceColorAlpha.mImage.mImage and mSourceAlpha.mImage.mImage
|
||||
* respectively.
|
||||
*/
|
||||
nsresult BuildSourceImages();
|
||||
|
||||
// Allocates an image surface that covers mSurfaceRect (it uses
|
||||
// device offsets so that its origin is positioned at mSurfaceRect.TopLeft()
|
||||
// when using cairo to draw into the surface). The surface is cleared
|
||||
// to transparent black.
|
||||
/**
|
||||
* Build the graph of PrimitiveInfo nodes that describes the filter's filter
|
||||
* primitives and their connections. This populates mPrimitives, and sets
|
||||
* each PrimitiveInfo's mFE, mInputs, mImageUsers, mFilterPrimitiveSubregion,
|
||||
* etc.
|
||||
*/
|
||||
nsresult BuildPrimitives();
|
||||
|
||||
/**
|
||||
* Compute the filter space bounds of the output from each primitive, were we
|
||||
* to do a full repaint of mTargetFrame. This sets mResultBoundingBox on the
|
||||
* items in the filter graph, based on the mResultBoundingBox of each item's
|
||||
* inputs, and clipped to the filter region and each primitive's filter
|
||||
* primitive subregion.
|
||||
*/
|
||||
void ComputeResultBoundingBoxes();
|
||||
|
||||
/**
|
||||
* Computes the filter space bounds of the areas that we actually *need* from
|
||||
* each filter primitive's output, based on the value of mDirtyOutputRect.
|
||||
* This sets mResultNeededBox on the items in the filter graph.
|
||||
*/
|
||||
void ComputeNeededBoxes();
|
||||
|
||||
/**
|
||||
* Computes the filter space bounds of the area of each filter primitive
|
||||
* that will change, based on the value of mDirtyInputRect.
|
||||
* This sets mResultChangeBox on the items in the filter graph.
|
||||
*/
|
||||
void ComputeResultChangeBoxes();
|
||||
|
||||
/**
|
||||
* Computes and returns the union of all mResultNeededBox rects in the filter
|
||||
* graph. This is useful for deciding the size of the offscreen surface that
|
||||
* needs to be created for the filter operation.
|
||||
*/
|
||||
nsIntRect ComputeUnionOfAllNeededBoxes();
|
||||
|
||||
/**
|
||||
* Allocates and returns a surface of mSurfaceRect.Size(), and with a device
|
||||
* offset of -mSurfaceRect.TopLeft(). The surface is cleared to transparent
|
||||
* black.
|
||||
*/
|
||||
already_AddRefed<gfxImageSurface> CreateImage();
|
||||
|
||||
/**
|
||||
* Computes and sets mFilterPrimitiveSubregion for the given primitive.
|
||||
*/
|
||||
void ComputeFilterPrimitiveSubregion(PrimitiveInfo* aInfo);
|
||||
|
||||
/**
|
||||
* If the color model of the pixel data in the aPrimitive's image isn't
|
||||
* already aColorModel, then this method converts its pixel data to that
|
||||
* color model.
|
||||
*/
|
||||
void EnsureColorModel(PrimitiveInfo* aPrimitive,
|
||||
ColorModel aColorModel);
|
||||
|
||||
@ -199,26 +367,58 @@ private:
|
||||
float GetPrimitiveNumber(PRUint8 aCtxType, float aValue) const;
|
||||
|
||||
gfxRect UserSpaceToFilterSpace(const gfxRect& aUserSpace) const;
|
||||
|
||||
/**
|
||||
* Clip the filter space rect aRect to the filter region.
|
||||
*/
|
||||
void ClipToFilterSpace(nsIntRect* aRect) const
|
||||
{
|
||||
nsIntRect filterSpace(nsIntPoint(0, 0), mFilterSpaceSize);
|
||||
aRect->IntersectRect(*aRect, filterSpace);
|
||||
}
|
||||
void ClipToGfxRect(nsIntRect* aRect, const gfxRect& aGfx) const;
|
||||
|
||||
/**
|
||||
* The frame for the element that is currently being filtered.
|
||||
*/
|
||||
nsIFrame* mTargetFrame;
|
||||
|
||||
nsSVGFilterPaintCallback* mPaintCallback;
|
||||
const nsSVGFilterElement* mFilterElement;
|
||||
// Bounding box of the target element, in user space
|
||||
|
||||
/**
|
||||
* The SVG bbox of the element that is being filtered, in user space.
|
||||
*/
|
||||
gfxRect mTargetBBox;
|
||||
|
||||
gfxMatrix mFilterSpaceToDeviceSpaceTransform;
|
||||
gfxRect mFilterRect;
|
||||
nsIntSize mFilterSpaceSize;
|
||||
// Filter-space bounds of the target image (SourceAlpha/SourceGraphic)
|
||||
nsIntRect mTargetBounds;
|
||||
nsIntRect mDirtyOutputRect;
|
||||
nsIntRect mDirtyInputRect;
|
||||
nsIntRect mSurfaceRect;
|
||||
|
||||
/**
|
||||
* Pre-filter paint bounds of the element that is being filtered, in filter
|
||||
* space.
|
||||
*/
|
||||
nsIntRect mTargetBounds;
|
||||
|
||||
/**
|
||||
* If set, this is the filter space bounds of the outer-<svg> device space
|
||||
* bounds of the dirty area that needs to be repainted. (As bounds-of-bounds,
|
||||
* this may be a fair bit bigger than we actually need, unfortunately.)
|
||||
*/
|
||||
nsIntRect mDirtyOutputRect;
|
||||
|
||||
/**
|
||||
* If set, this is the filter space bounds of the outer-<svg> device bounds
|
||||
* of the pre-filter area of the filtered element that changed. (As
|
||||
* bounds-of-bounds, this may be a fair bit bigger than we actually need,
|
||||
* unfortunately.)
|
||||
*/
|
||||
nsIntRect mDirtyInputRect;
|
||||
|
||||
/**
|
||||
* The 'primitiveUnits' attribute value (objectBoundingBox or userSpaceOnUse).
|
||||
*/
|
||||
PRUint16 mPrimitiveUnits;
|
||||
|
||||
PrimitiveInfo mSourceColorAlpha;
|
||||
|
@ -542,7 +542,9 @@ public:
|
||||
static gfxRect GetBBox(nsIFrame *aFrame, PRUint32 aFlags = eBBoxIncludeFill);
|
||||
|
||||
/**
|
||||
* Compute a rectangle in userSpaceOnUse or objectBoundingBoxUnits.
|
||||
* Convert a userSpaceOnUse/objectBoundingBoxUnits rectangle that's specified
|
||||
* using four nsSVGLength2 values into a user unit rectangle in user space.
|
||||
*
|
||||
* @param aXYWH pointer to 4 consecutive nsSVGLength2 objects containing
|
||||
* the x, y, width and height values in that order
|
||||
* @param aBBox the bounding box of the object the rect is relative to;
|
||||
|
Loading…
Reference in New Issue
Block a user