/*
 * 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 {

/** Maximum sigma before the implementation downscales the input image. */
static constexpr float kMaxSigma = 4.f;

#if GR_OGA
/**
 * 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);
#endif

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);

void Compute1DLinearGaussianKernel(float* kernel, float* offset, 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; }

inline int LinearKernelWidth(int radius) { return radius + 1; }

}  // namespace SkGpuBlurUtils

#endif
#endif
