/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkGpuBlurUtils_DEFINED
#define SkGpuBlurUtils_DEFINED

#include "include/core/SkTypes.h"

#if SK_SUPPORT_GPU
#include "src/gpu/GrSurfaceDrawContext.h"

class GrRecordingContext;
class GrTexture;

struct SkRect;

namespace SkGpuBlurUtils {

/**
 * Applies a 2D Gaussian blur to a given texture. The blurred result is returned
 * as a surfaceDrawContext in case the caller wishes to draw into the result.
 * The GrSurfaceOrigin of the result will watch the GrSurfaceOrigin of srcView. The output
 * color type, color space, and alpha type will be the same as the src.
 *
 * Note: one of sigmaX and sigmaY should be non-zero!
 * @param context         The GPU context
 * @param srcView         The source to be blurred.
 * @param srcColorType    The colorType of srcProxy
 * @param srcAlphaType    The alphaType of srcProxy
 * @param colorSpace      Color space of the source.
 * @param dstBounds       The destination bounds, relative to the source texture.
 * @param srcBounds       The source bounds, relative to the source texture's offset. No pixels
 *                        will be sampled outside of this rectangle.
 * @param sigmaX          The blur's standard deviation in X.
 * @param sigmaY          The blur's standard deviation in Y.
 * @param tileMode        The mode to handle samples outside bounds.
 * @param fit             backing fit for the returned render target context
 * @return                The surfaceDrawContext containing the blurred result.
 */
std::unique_ptr<GrSurfaceDrawContext> GaussianBlur(GrRecordingContext* context,
                                                   GrSurfaceProxyView srcView,
                                                   GrColorType srcColorType,
                                                   SkAlphaType srcAlphaType,
                                                   sk_sp<SkColorSpace> colorSpace,
                                                   SkIRect dstBounds,
                                                   SkIRect srcBounds,
                                                   float sigmaX,
                                                   float sigmaY,
                                                   SkTileMode mode,
                                                   SkBackingFit fit = SkBackingFit::kApprox);

static const int kBlurRRectMaxDivisions = 6;

// This method computes all the parameters for drawing a partially occluded nine-patched
// blurred rrect mask:
//   rrectToDraw - the integerized rrect to draw in the mask
//   widthHeight - how large to make the mask (rrectToDraw will be centered in this coord sys)
//   rectXs, rectYs - the x & y coordinates of the covering geometry lattice
//   texXs, texYs - the texture coordinate at each point in rectXs & rectYs
// It returns true if 'devRRect' is nine-patchable
bool ComputeBlurredRRectParams(const SkRRect& srcRRect, const SkRRect& devRRect,
                                SkScalar sigma, SkScalar xformedSigma,
                                SkRRect* rrectToDraw,
                                SkISize* widthHeight,
                                SkScalar rectXs[kBlurRRectMaxDivisions],
                                SkScalar rectYs[kBlurRRectMaxDivisions],
                                SkScalar texXs[kBlurRRectMaxDivisions],
                                SkScalar texYs[kBlurRRectMaxDivisions]);

int CreateIntegralTable(float sixSigma, SkBitmap* table);

void Compute1DGaussianKernel(float* kernel, float sigma, int radius);

// Any sigmas smaller than this are effectively an identity blur so can skip convolution at a higher
// level. The value was chosen because it corresponds roughly to a radius of 1/10px, and is slightly
// greater than sqrt(1/2*sigma^2) for SK_ScalarNearlyZero.
inline bool IsEffectivelyZeroSigma(float sigma) { return sigma <= 0.03f; }

inline int SigmaRadius(float sigma) {
    return IsEffectivelyZeroSigma(sigma) ? 0 : static_cast<int>(ceilf(sigma * 3.0f));
}

inline int KernelWidth(int radius) { return 2 * radius + 1; }

}  // namespace SkGpuBlurUtils

#endif
#endif
