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 GrRRectBlurEffect.fp; do not modify.
10 **************************************************************************************************/
11#ifndef GrRRectBlurEffect_DEFINED
12#define GrRRectBlurEffect_DEFINED
13#include "SkTypes.h"
14#if SK_SUPPORT_GPU
15
16#include "GrClip.h"
17#include "GrContext.h"
18#include "GrContextPriv.h"
19#include "GrPaint.h"
20#include "GrProxyProvider.h"
21#include "GrRenderTargetContext.h"
22#include "GrStyle.h"
23#include "SkBlurMaskFilter.h"
24#include "SkGpuBlurUtils.h"
25#include "SkRRectPriv.h"
26#include "GrFragmentProcessor.h"
27#include "GrCoordTransform.h"
28class GrRRectBlurEffect : public GrFragmentProcessor {
29public:
30    static sk_sp<GrTextureProxy> find_or_create_rrect_blur_mask(GrContext* context,
31                                                                const SkRRect& rrectToDraw,
32                                                                const SkISize& size,
33                                                                float xformedSigma) {
34        static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
35        GrUniqueKey key;
36        GrUniqueKey::Builder builder(&key, kDomain, 9, "RoundRect Blur Mask");
37        builder[0] = SkScalarCeilToInt(xformedSigma - 1 / 6.0f);
38
39        int index = 1;
40        for (auto c : {SkRRect::kUpperLeft_Corner, SkRRect::kUpperRight_Corner,
41                       SkRRect::kLowerRight_Corner, SkRRect::kLowerLeft_Corner}) {
42            SkASSERT(SkScalarIsInt(rrectToDraw.radii(c).fX) &&
43                     SkScalarIsInt(rrectToDraw.radii(c).fY));
44            builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fX);
45            builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fY);
46        }
47        builder.finish();
48
49        GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
50
51        sk_sp<GrTextureProxy> mask(
52                proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin));
53        if (!mask) {
54            // TODO: this could be approx but the texture coords will need to be updated
55            sk_sp<GrRenderTargetContext> rtc(context->makeDeferredRenderTargetContextWithFallback(
56                    SkBackingFit::kExact, size.fWidth, size.fHeight, kAlpha_8_GrPixelConfig,
57                    nullptr));
58            if (!rtc) {
59                return nullptr;
60            }
61
62            GrPaint paint;
63
64            rtc->clear(nullptr, 0x0, GrRenderTargetContext::CanClearFullscreen::kYes);
65            rtc->drawRRect(GrNoClip(), std::move(paint), GrAA::kYes, SkMatrix::I(), rrectToDraw,
66                           GrStyle::SimpleFill());
67
68            sk_sp<GrTextureProxy> srcProxy(rtc->asTextureProxyRef());
69            if (!srcProxy) {
70                return nullptr;
71            }
72            sk_sp<GrRenderTargetContext> rtc2(
73                    SkGpuBlurUtils::GaussianBlur(context,
74                                                 std::move(srcProxy),
75                                                 nullptr,
76                                                 SkIRect::MakeWH(size.fWidth, size.fHeight),
77                                                 SkIRect::EmptyIRect(),
78                                                 xformedSigma,
79                                                 xformedSigma,
80                                                 GrTextureDomain::kIgnore_Mode,
81                                                 SkBackingFit::kExact));
82            if (!rtc2) {
83                return nullptr;
84            }
85
86            mask = rtc2->asTextureProxyRef();
87            if (!mask) {
88                return nullptr;
89            }
90            SkASSERT(mask->origin() == kBottomLeft_GrSurfaceOrigin);
91            proxyProvider->assignUniqueKeyToProxy(key, mask.get());
92        }
93
94        return mask;
95    }
96    float sigma() const { return fSigma; }
97    SkRect rect() const { return fRect; }
98    float cornerRadius() const { return fCornerRadius; }
99
100    static std::unique_ptr<GrFragmentProcessor> Make(GrContext* context, float sigma,
101                                                     float xformedSigma, const SkRRect& srcRRect,
102                                                     const SkRRect& devRRect);
103    GrRRectBlurEffect(const GrRRectBlurEffect& src);
104    std::unique_ptr<GrFragmentProcessor> clone() const override;
105    const char* name() const override { return "RRectBlurEffect"; }
106
107private:
108    GrRRectBlurEffect(float sigma, SkRect rect, float cornerRadius,
109                      sk_sp<GrTextureProxy> ninePatchSampler)
110            : INHERITED(kGrRRectBlurEffect_ClassID,
111                        (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
112            , fSigma(sigma)
113            , fRect(rect)
114            , fCornerRadius(cornerRadius)
115            , fNinePatchSampler(std::move(ninePatchSampler)) {
116        this->addTextureSampler(&fNinePatchSampler);
117    }
118    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
119    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
120    bool onIsEqual(const GrFragmentProcessor&) const override;
121    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
122    float fSigma;
123    SkRect fRect;
124    float fCornerRadius;
125    TextureSampler fNinePatchSampler;
126    typedef GrFragmentProcessor INHERITED;
127};
128#endif
129#endif
130