
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkMaskFilter_DEFINED
#define SkMaskFilter_DEFINED

#include "SkBlurTypes.h"
#include "SkFlattenable.h"
#include "SkMask.h"
#include "SkPaint.h"
#include "SkStrokeRec.h"

class GrClip;
class GrContext;
class GrRenderTargetContext;
class GrPaint;
class GrFragmentProcessor;
class GrRenderTarget;
class GrResourceProvider;
class GrTexture;
class GrTextureProxy;
class SkBitmap;
class SkBlitter;
class SkCachedData;
class SkMatrix;
class SkPath;
class SkRasterClip;
class SkRRect;

/** \class SkMaskFilter

    SkMaskFilter is the base class for object that perform transformations on
    an alpha-channel mask before drawing it. A subclass of SkMaskFilter may be
    installed into a SkPaint. Once there, each time a primitive is drawn, it
    is first scan converted into a SkMask::kA8_Format mask, and handed to the
    filter, calling its filterMask() method. If this returns true, then the
    new mask is used to render into the device.

    Blur and emboss are implemented as subclasses of SkMaskFilter.
*/
class SK_API SkMaskFilter : public SkFlattenable {
public:
    /** Returns the format of the resulting mask that this subclass will return
        when its filterMask() method is called.
    */
    virtual SkMask::Format getFormat() const = 0;

    /** Create a new mask by filter the src mask.
        If src.fImage == null, then do not allocate or create the dst image
        but do fill out the other fields in dstMask.
        If you do allocate a dst image, use SkMask::AllocImage()
        If this returns false, dst mask is ignored.
        @param  dst the result of the filter. If src.fImage == null, dst should not allocate its image
        @param src the original image to be filtered.
        @param matrix the CTM
        @param margin   if not null, return the buffer dx/dy need when calculating the effect. Used when
                        drawing a clipped object to know how much larger to allocate the src before
                        applying the filter. If returning false, ignore this parameter.
        @return true if the dst mask was correctly created.
    */
    virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
                            SkIPoint* margin) const;

#if SK_SUPPORT_GPU
    /**
     *  Returns true if the filter can be expressed a single-pass GrProcessor without requiring an
     *  explicit input mask. Per-pixel, the effect receives the incoming mask's coverage as
     *  the input color and outputs the filtered covereage value. This means that each pixel's
     *  filtered coverage must only depend on the unfiltered mask value for that pixel and not on
     *  surrounding values.
     *
     * If effect is non-NULL, a new GrProcessor instance is stored in it. The caller assumes
     * ownership of the effect and must unref it.
     */
    virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix& ctm) const;

    /**
     *  If asFragmentProcessor() fails the filter may be implemented on the GPU by a subclass
     *  overriding filterMaskGPU (declared below). That code path requires constructing a
     *  src mask as input. Since that is a potentially expensive operation, the subclass must also
     *  override this function to indicate whether filterTextureMaskGPU would succeeed if the mask
     *  were to be created.
     *
     *  'maskRect' returns the device space portion of the mask that the filter needs. The mask
     *  passed into 'filterMaskGPU' should have the same extent as 'maskRect' but be
     *  translated to the upper-left corner of the mask (i.e., (maskRect.fLeft, maskRect.fTop)
     *  appears at (0, 0) in the mask).
     *
     * Logically, how this works is:
     *    canFilterMaskGPU is called
     *    if (it returns true)
     *        the returned mask rect is used for quick rejecting
     *        either directFilterMaskGPU or directFilterRRectMaskGPU is then called
     *        if (neither of them handle the blur)
     *            the mask rect is used to generate the mask
     *            filterMaskGPU is called to filter the mask
     *
     * TODO: this should work as:
     *    if (canFilterMaskGPU(devShape, ...)) // rect, rrect, drrect, path
     *        filterMaskGPU(devShape, ...)
     * this would hide the RRect special case and the mask generation
     */
    virtual bool canFilterMaskGPU(const SkRRect& devRRect,
                                  const SkIRect& clipBounds,
                                  const SkMatrix& ctm,
                                  SkRect* maskRect) const;

    /**
     *  Try to directly render the mask filter into the target. Returns true if drawing was
     *  successful. If false is returned then paint is unmodified.
     */
    virtual bool directFilterMaskGPU(GrContext*,
                                     GrRenderTargetContext* renderTargetContext,
                                     GrPaint&& paint,
                                     const GrClip&,
                                     const SkMatrix& viewMatrix,
                                     const SkStrokeRec& strokeRec,
                                     const SkPath& path) const;
    /**
     *  Try to directly render a rounded rect mask filter into the target.  Returns
     *  true if drawing was successful.  If false is returned then paint is unmodified.
     */
    virtual bool directFilterRRectMaskGPU(GrContext*,
                                          GrRenderTargetContext* renderTargetContext,
                                          GrPaint&& paint,
                                          const GrClip&,
                                          const SkMatrix& viewMatrix,
                                          const SkStrokeRec& strokeRec,
                                          const SkRRect& rrect,
                                          const SkRRect& devRRect) const;

    /**
     * This function is used to implement filters that require an explicit src mask. It should only
     * be called if canFilterMaskGPU returned true and the maskRect param should be the output from
     * that call.
     * Implementations are free to get the GrContext from the src texture in order to create
     * additional textures and perform multiple passes.
     */
    virtual sk_sp<GrTextureProxy> filterMaskGPU(GrContext*,
                                                sk_sp<GrTextureProxy> srcProxy,
                                                const SkMatrix& ctm,
                                                const SkIRect& maskRect) const;
#endif

    /**
     * The fast bounds function is used to enable the paint to be culled early
     * in the drawing pipeline. This function accepts the current bounds of the
     * paint as its src param and the filter adjust those bounds using its
     * current mask and returns the result using the dest param. Callers are
     * allowed to provide the same struct for both src and dest so each
     * implementation must accomodate that behavior.
     *
     *  The default impl calls filterMask with the src mask having no image,
     *  but subclasses may override this if they can compute the rect faster.
     */
    virtual void computeFastBounds(const SkRect& src, SkRect* dest) const;

    struct BlurRec {
        SkScalar        fSigma;
        SkBlurStyle     fStyle;
        SkBlurQuality   fQuality;
    };
    /**
     *  If this filter can be represented by a BlurRec, return true and (if not null) fill in the
     *  provided BlurRec parameter. If this effect cannot be represented as a BlurRec, return false
     *  and ignore the BlurRec parameter.
     */
    virtual bool asABlur(BlurRec*) const;

    SK_TO_STRING_PUREVIRT()
    SK_DEFINE_FLATTENABLE_TYPE(SkMaskFilter)

protected:
    SkMaskFilter() {}

    enum FilterReturn {
        kFalse_FilterReturn,
        kTrue_FilterReturn,
        kUnimplemented_FilterReturn
    };

    class NinePatch : ::SkNoncopyable {
    public:
        NinePatch() : fCache(nullptr) { }
        ~NinePatch();

        SkMask      fMask;      // fBounds must have [0,0] in its top-left
        SkIRect     fOuterRect; // width/height must be >= fMask.fBounds'
        SkIPoint    fCenter;    // identifies center row/col for stretching
        SkCachedData* fCache;
    };

    /**
     *  Override if your subclass can filter a rect, and return the answer as
     *  a ninepatch mask to be stretched over the returned outerRect. On success
     *  return kTrue_FilterReturn. On failure (e.g. out of memory) return
     *  kFalse_FilterReturn. If the normal filterMask() entry-point should be
     *  called (the default) return kUnimplemented_FilterReturn.
     *
     *  By convention, the caller will take the center rol/col from the returned
     *  mask as the slice it can replicate horizontally and vertically as we
     *  stretch the mask to fit inside outerRect. It is an error for outerRect
     *  to be smaller than the mask's bounds. This would imply that the width
     *  and height of the mask should be odd. This is not required, just that
     *  the caller will call mask.fBounds.centerX() and centerY() to find the
     *  strips that will be replicated.
     */
    virtual FilterReturn filterRectsToNine(const SkRect[], int count,
                                           const SkMatrix&,
                                           const SkIRect& clipBounds,
                                           NinePatch*) const;
    /**
     *  Similar to filterRectsToNine, except it performs the work on a round rect.
     */
    virtual FilterReturn filterRRectToNine(const SkRRect&, const SkMatrix&,
                                           const SkIRect& clipBounds,
                                           NinePatch*) const;

private:
    friend class SkDraw;

    /** Helper method that, given a path in device space, will rasterize it into a kA8_Format mask
     and then call filterMask(). If this returns true, the specified blitter will be called
     to render that mask. Returns false if filterMask() returned false.
     This method is not exported to java.
     */
    bool filterPath(const SkPath& devPath, const SkMatrix& ctm, const SkRasterClip&, SkBlitter*,
                    SkStrokeRec::InitStyle) const;

    /** Helper method that, given a roundRect in device space, will rasterize it into a kA8_Format
     mask and then call filterMask(). If this returns true, the specified blitter will be called
     to render that mask. Returns false if filterMask() returned false.
     */
    bool filterRRect(const SkRRect& devRRect, const SkMatrix& ctm, const SkRasterClip&,
                     SkBlitter*) const;

    typedef SkFlattenable INHERITED;
};

#endif
