aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/effects/GrRRectBlurEffect.h
blob: d1316e8a5b39af8bc5a56e093475750889c473f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/**************************************************************************************************
 *** This file was autogenerated from GrRRectBlurEffect.fp; do not modify.
 **************************************************************************************************/
#ifndef GrRRectBlurEffect_DEFINED
#define GrRRectBlurEffect_DEFINED
#include "SkTypes.h"

#include "GrClip.h"
#include "GrContext.h"
#include "GrContextPriv.h"
#include "GrPaint.h"
#include "GrProxyProvider.h"
#include "GrRenderTargetContext.h"
#include "GrStyle.h"
#include "SkBlurMaskFilter.h"
#include "SkBlurPriv.h"
#include "SkGpuBlurUtils.h"
#include "SkRRectPriv.h"
#include "GrFragmentProcessor.h"
#include "GrCoordTransform.h"
class GrRRectBlurEffect : public GrFragmentProcessor {
public:
    static sk_sp<GrTextureProxy> find_or_create_rrect_blur_mask(GrContext* context,
                                                                const SkRRect& rrectToDraw,
                                                                const SkISize& size,
                                                                float xformedSigma) {
        static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
        GrUniqueKey key;
        GrUniqueKey::Builder builder(&key, kDomain, 9, "RoundRect Blur Mask");
        builder[0] = SkScalarCeilToInt(xformedSigma - 1 / 6.0f);

        int index = 1;
        for (auto c : {SkRRect::kUpperLeft_Corner, SkRRect::kUpperRight_Corner,
                       SkRRect::kLowerRight_Corner, SkRRect::kLowerLeft_Corner}) {
            SkASSERT(SkScalarIsInt(rrectToDraw.radii(c).fX) &&
                     SkScalarIsInt(rrectToDraw.radii(c).fY));
            builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fX);
            builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fY);
        }
        builder.finish();

        GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();

        sk_sp<GrTextureProxy> mask(
                proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin));
        if (!mask) {
            // TODO: this could be approx but the texture coords will need to be updated
            sk_sp<GrRenderTargetContext> rtc(
                    context->contextPriv().makeDeferredRenderTargetContextWithFallback(
                            SkBackingFit::kExact, size.fWidth, size.fHeight, kAlpha_8_GrPixelConfig,
                            nullptr));
            if (!rtc) {
                return nullptr;
            }

            GrPaint paint;

            rtc->clear(nullptr, 0x0, GrRenderTargetContext::CanClearFullscreen::kYes);
            rtc->drawRRect(GrNoClip(), std::move(paint), GrAA::kYes, SkMatrix::I(), rrectToDraw,
                           GrStyle::SimpleFill());

            sk_sp<GrTextureProxy> srcProxy(rtc->asTextureProxyRef());
            if (!srcProxy) {
                return nullptr;
            }
            sk_sp<GrRenderTargetContext> rtc2(
                    SkGpuBlurUtils::GaussianBlur(context,
                                                 std::move(srcProxy),
                                                 nullptr,
                                                 SkIRect::MakeWH(size.fWidth, size.fHeight),
                                                 SkIRect::EmptyIRect(),
                                                 xformedSigma,
                                                 xformedSigma,
                                                 GrTextureDomain::kIgnore_Mode,
                                                 SkBackingFit::kExact));
            if (!rtc2) {
                return nullptr;
            }

            mask = rtc2->asTextureProxyRef();
            if (!mask) {
                return nullptr;
            }
            SkASSERT(mask->origin() == kBottomLeft_GrSurfaceOrigin);
            proxyProvider->assignUniqueKeyToProxy(key, mask.get());
        }

        return mask;
    }
    float sigma() const { return fSigma; }
    SkRect rect() const { return fRect; }
    float cornerRadius() const { return fCornerRadius; }

    static std::unique_ptr<GrFragmentProcessor> Make(GrContext* context, float sigma,
                                                     float xformedSigma, const SkRRect& srcRRect,
                                                     const SkRRect& devRRect);
    GrRRectBlurEffect(const GrRRectBlurEffect& src);
    std::unique_ptr<GrFragmentProcessor> clone() const override;
    const char* name() const override { return "RRectBlurEffect"; }

private:
    GrRRectBlurEffect(float sigma, SkRect rect, float cornerRadius,
                      sk_sp<GrTextureProxy> ninePatchSampler)
            : INHERITED(kGrRRectBlurEffect_ClassID,
                        (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
            , fSigma(sigma)
            , fRect(rect)
            , fCornerRadius(cornerRadius)
            , fNinePatchSampler(std::move(ninePatchSampler)) {
        this->addTextureSampler(&fNinePatchSampler);
    }
    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
    bool onIsEqual(const GrFragmentProcessor&) const override;
    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
    float fSigma;
    SkRect fRect;
    float fCornerRadius;
    TextureSampler fNinePatchSampler;
    typedef GrFragmentProcessor INHERITED;
};
#endif