aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/GrAlphaThresholdFragmentProcessor.cpp
blob: 731ca99d3b1dbb4be062b037622666903fa6e8ad (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * Copyright 2017 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 GrAlphaThresholdFragmentProcessor.fp; do not modify.
 */
#include "GrAlphaThresholdFragmentProcessor.h"
#if SK_SUPPORT_GPU

inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor::optFlags(
        float outerThreshold) {
    if (outerThreshold >= 1.0) {
        return kPreservesOpaqueInput_OptimizationFlag |
               kCompatibleWithCoverageAsAlpha_OptimizationFlag;
    } else {
        return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
    }
}
#include "glsl/GrGLSLColorSpaceXformHelper.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramBuilder.h"
#include "SkSLCPP.h"
#include "SkSLUtil.h"
class GrGLSLAlphaThresholdFragmentProcessor : public GrGLSLFragmentProcessor {
public:
    GrGLSLAlphaThresholdFragmentProcessor() {}
    void emitCode(EmitArgs& args) override {
        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
        const GrAlphaThresholdFragmentProcessor& _outer =
                args.fFp.cast<GrAlphaThresholdFragmentProcessor>();
        (void)_outer;
        fColorSpaceHelper.emitCode(args.fUniformHandler, _outer.colorXform().get());
        fInnerThresholdVar = args.fUniformHandler->addUniform(
                kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "innerThreshold");
        fOuterThresholdVar = args.fUniformHandler->addUniform(
                kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "outerThreshold");
        SkSL::String sk_TransformedCoords2D_0 =
                fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
        SkSL::String sk_TransformedCoords2D_1 =
                fragBuilder->ensureCoords2D(args.fTransformedCoords[1]);
        fragBuilder->codeAppendf(
                "float4 _tmpVar1;float4 color = %stexture(%s, %s).%s%s;\nfloat4 mask_color = "
                "texture(%s, %s).%s;\nif (mask_color.w < 0.5) {\n    if (color.w > %s) {\n        "
                "float scale = %s / color.w;\n        color.xyz *= scale;\n        color.w = %s;\n "
                "   }\n} else if (color.w < %s) {\n    float scale = %s / max(0.001, color.w);\n   "
                " color.xyz *= scale;\n    color.w = %s;\n}\n%s = color;\n",
                fColorSpaceHelper.isValid() ? "(_tmpVar1 = " : "",
                fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
                sk_TransformedCoords2D_0.c_str(),
                fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
                fColorSpaceHelper.isValid()
                        ? SkStringPrintf(", float4(clamp((%s * float4(_tmpVar1.rgb, 1.0)).rgb, "
                                         "0.0, _tmpVar1.a), _tmpVar1.a))",
                                         args.fUniformHandler->getUniformCStr(
                                                 fColorSpaceHelper.gamutXformUniform()))
                                  .c_str()
                        : "",
                fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[1]).c_str(),
                sk_TransformedCoords2D_1.c_str(),
                fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[1]).c_str(),
                args.fUniformHandler->getUniformCStr(fOuterThresholdVar),
                args.fUniformHandler->getUniformCStr(fOuterThresholdVar),
                args.fUniformHandler->getUniformCStr(fOuterThresholdVar),
                args.fUniformHandler->getUniformCStr(fInnerThresholdVar),
                args.fUniformHandler->getUniformCStr(fInnerThresholdVar),
                args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fOutputColor);
    }

private:
    void onSetData(const GrGLSLProgramDataManager& pdman,
                   const GrFragmentProcessor& _proc) override {
        const GrAlphaThresholdFragmentProcessor& _outer =
                _proc.cast<GrAlphaThresholdFragmentProcessor>();
        {
            if (fColorSpaceHelper.isValid()) {
                fColorSpaceHelper.setData(pdman, _outer.colorXform().get());
            }
            pdman.set1f(fInnerThresholdVar, _outer.innerThreshold());
            pdman.set1f(fOuterThresholdVar, _outer.outerThreshold());
        }
    }
    UniformHandle fImageVar;
    UniformHandle fMaskVar;
    UniformHandle fInnerThresholdVar;
    UniformHandle fOuterThresholdVar;
    GrGLSLColorSpaceXformHelper fColorSpaceHelper;
};
GrGLSLFragmentProcessor* GrAlphaThresholdFragmentProcessor::onCreateGLSLInstance() const {
    return new GrGLSLAlphaThresholdFragmentProcessor();
}
void GrAlphaThresholdFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                              GrProcessorKeyBuilder* b) const {
    b->add32(GrColorSpaceXform::XformKey(fColorXform.get()));
}
bool GrAlphaThresholdFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
    const GrAlphaThresholdFragmentProcessor& that = other.cast<GrAlphaThresholdFragmentProcessor>();
    (void)that;
    if (fImage != that.fImage) return false;
    if (fColorXform != that.fColorXform) return false;
    if (fMask != that.fMask) return false;
    if (fInnerThreshold != that.fInnerThreshold) return false;
    if (fOuterThreshold != that.fOuterThreshold) return false;
    return true;
}
GrAlphaThresholdFragmentProcessor::GrAlphaThresholdFragmentProcessor(
        const GrAlphaThresholdFragmentProcessor& src)
        : INHERITED(src.optimizationFlags())
        , fImage(src.fImage)
        , fColorXform(src.fColorXform)
        , fMask(src.fMask)
        , fInnerThreshold(src.fInnerThreshold)
        , fOuterThreshold(src.fOuterThreshold)
        , fImageCoordTransform(src.fImageCoordTransform)
        , fMaskCoordTransform(src.fMaskCoordTransform) {
    this->initClassID<GrAlphaThresholdFragmentProcessor>();
    this->addTextureSampler(&fImage);
    this->addTextureSampler(&fMask);
    this->addCoordTransform(&fImageCoordTransform);
    this->addCoordTransform(&fMaskCoordTransform);
}
sk_sp<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::clone() const {
    return sk_sp<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor(*this));
}
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrAlphaThresholdFragmentProcessor);
#if GR_TEST_UTILS
sk_sp<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::TestCreate(
        GrProcessorTestData* testData) {
    sk_sp<GrTextureProxy> bmpProxy = testData->textureProxy(GrProcessorUnitTest::kSkiaPMTextureIdx);
    sk_sp<GrTextureProxy> maskProxy = testData->textureProxy(GrProcessorUnitTest::kAlphaTextureIdx);

    float innerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
    float outerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
    const int kMaxWidth = 1000;
    const int kMaxHeight = 1000;
    uint32_t width = testData->fRandom->nextULessThan(kMaxWidth);
    uint32_t height = testData->fRandom->nextULessThan(kMaxHeight);
    uint32_t x = testData->fRandom->nextULessThan(kMaxWidth - width);
    uint32_t y = testData->fRandom->nextULessThan(kMaxHeight - height);
    SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height);
    sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(testData->fRandom);
    return GrAlphaThresholdFragmentProcessor::Make(std::move(bmpProxy), colorSpaceXform,
                                                   std::move(maskProxy), innerThresh, outerThresh,
                                                   bounds);
}
#endif
#endif