1/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8/**************************************************************************************************
9 *** This file was autogenerated from GrRectBlurEffect.fp; do not modify.
10 **************************************************************************************************/
11#ifndef GrRectBlurEffect_DEFINED
12#define GrRectBlurEffect_DEFINED
13#include "SkTypes.h"
14#if SK_SUPPORT_GPU
15
16#include "GrProxyProvider.h"
17#include "../effects/SkBlurMask.h"
18#include "GrFragmentProcessor.h"
19#include "GrCoordTransform.h"
20class GrRectBlurEffect : public GrFragmentProcessor {
21public:
22    static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrProxyProvider* proxyProvider,
23                                                          float sigma) {
24        unsigned int profileSize = SkScalarCeilToInt(6 * sigma);
25
26        static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
27        GrUniqueKey key;
28        GrUniqueKey::Builder builder(&key, kDomain, 1, "Rect Blur Mask");
29        builder[0] = profileSize;
30        builder.finish();
31
32        sk_sp<GrTextureProxy> blurProfile(
33                proxyProvider->findOrCreateProxyByUniqueKey(key, kTopLeft_GrSurfaceOrigin));
34        if (!blurProfile) {
35            SkImageInfo ii = SkImageInfo::MakeA8(profileSize, 1);
36
37            SkBitmap bitmap;
38            if (!bitmap.tryAllocPixels(ii)) {
39                return nullptr;
40            }
41
42            SkBlurMask::ComputeBlurProfile(bitmap.getAddr8(0, 0), profileSize, sigma);
43            bitmap.setImmutable();
44
45            sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
46            if (!image) {
47                return nullptr;
48            }
49
50            blurProfile = proxyProvider->createTextureProxy(std::move(image), kNone_GrSurfaceFlags,
51                                                            kTopLeft_GrSurfaceOrigin, 1,
52                                                            SkBudgeted::kYes, SkBackingFit::kExact);
53            if (!blurProfile) {
54                return nullptr;
55            }
56
57            SkASSERT(blurProfile->origin() == kTopLeft_GrSurfaceOrigin);
58            proxyProvider->assignUniqueKeyToProxy(key, blurProfile.get());
59        }
60
61        return blurProfile;
62    }
63    SkRect rect() const { return fRect; }
64    float sigma() const { return fSigma; }
65
66    static std::unique_ptr<GrFragmentProcessor> Make(GrProxyProvider* proxyProvider,
67                                                     const SkRect& rect, float sigma) {
68        int doubleProfileSize = SkScalarCeilToInt(12 * sigma);
69
70        if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.height()) {
71            // if the blur sigma is too large so the gaussian overlaps the whole
72            // rect in either direction, fall back to CPU path for now.
73            return nullptr;
74        }
75
76        sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(proxyProvider, sigma));
77        if (!blurProfile) {
78            return nullptr;
79        }
80
81        return std::unique_ptr<GrFragmentProcessor>(new GrRectBlurEffect(
82                rect, sigma, std::move(blurProfile),
83                GrSamplerState(GrSamplerState::WrapMode::kClamp, GrSamplerState::Filter::kBilerp)));
84    }
85    GrRectBlurEffect(const GrRectBlurEffect& src);
86    std::unique_ptr<GrFragmentProcessor> clone() const override;
87    const char* name() const override { return "RectBlurEffect"; }
88
89private:
90    GrRectBlurEffect(SkRect rect, float sigma, sk_sp<GrTextureProxy> blurProfile,
91                     GrSamplerState samplerParams)
92            : INHERITED(kGrRectBlurEffect_ClassID,
93                        (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
94            , fRect(rect)
95            , fSigma(sigma)
96            , fBlurProfile(std::move(blurProfile), samplerParams) {
97        this->addTextureSampler(&fBlurProfile);
98    }
99    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
100    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
101    bool onIsEqual(const GrFragmentProcessor&) const override;
102    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
103    SkRect fRect;
104    float fSigma;
105    TextureSampler fBlurProfile;
106    typedef GrFragmentProcessor INHERITED;
107};
108#endif
109#endif
110