1/*
2 * Copyright 2014 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#include "effects/GrDisableColorXP.h"
9#include "GrPipeline.h"
10#include "GrProcessor.h"
11#include "glsl/GrGLSLFragmentShaderBuilder.h"
12#include "glsl/GrGLSLProgramDataManager.h"
13#include "glsl/GrGLSLXferProcessor.h"
14
15/**
16 * This xfer processor disables color writing. Thus color and coverage and ignored and no blending
17 * occurs. This XP is usful for things like stenciling.
18 */
19class DisableColorXP : public GrXferProcessor {
20public:
21    DisableColorXP()
22    : INHERITED(kDisableColorXP_ClassID) {}
23
24    const char* name() const override { return "Disable Color"; }
25
26    GrGLSLXferProcessor* createGLSLInstance() const override;
27
28private:
29
30    void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
31
32    void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override;
33
34    bool onIsEqual(const GrXferProcessor& xpBase) const override {
35        return true;
36    }
37
38    typedef GrXferProcessor INHERITED;
39};
40
41///////////////////////////////////////////////////////////////////////////////
42
43class GLDisableColorXP : public GrGLSLXferProcessor {
44public:
45    GLDisableColorXP(const GrProcessor&) {}
46
47    ~GLDisableColorXP() override {}
48
49    static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder*) {}
50
51private:
52    void emitOutputsForBlendState(const EmitArgs& args) override {
53        // This emit code should be empty. However, on the nexus 6 there is a driver bug where if
54        // you do not give gl_FragColor a value, the gl context is lost and we end up drawing
55        // nothing. So this fix just sets the gl_FragColor arbitrarily to 0.
56        GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
57        fragBuilder->codeAppendf("%s = half4(0);", args.fOutputPrimary);
58    }
59
60    void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
61
62    typedef GrGLSLXferProcessor INHERITED;
63};
64
65///////////////////////////////////////////////////////////////////////////////
66
67void DisableColorXP::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
68    GLDisableColorXP::GenKey(*this, caps, b);
69}
70
71GrGLSLXferProcessor* DisableColorXP::createGLSLInstance() const { return new GLDisableColorXP(*this); }
72
73void DisableColorXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const {
74    blendInfo->fWriteColor = false;
75}
76
77///////////////////////////////////////////////////////////////////////////////
78sk_sp<const GrXferProcessor> GrDisableColorXPFactory::makeXferProcessor(
79        const GrProcessorAnalysisColor&,
80        GrProcessorAnalysisCoverage,
81        bool hasMixedSamples,
82        const GrCaps& caps,
83        GrPixelConfigIsClamped dstIsClamped) const {
84    return sk_sp<const GrXferProcessor>(new DisableColorXP);
85}
86
87GR_DEFINE_XP_FACTORY_TEST(GrDisableColorXPFactory);
88
89#if GR_TEST_UTILS
90const GrXPFactory* GrDisableColorXPFactory::TestGet(GrProcessorTestData*) {
91    return GrDisableColorXPFactory::Get();
92}
93#endif
94