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 "src/gpu/effects/GrDisableColorXP.h"
9 
10 #include "src/gpu/GrPipeline.h"
11 #include "src/gpu/GrProcessor.h"
12 #include "src/gpu/GrShaderCaps.h"
13 #include "src/gpu/GrXferProcessor.h"
14 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
15 #include "src/gpu/glsl/GrGLSLProgramDataManager.h"
16 
17 /**
18  * This xfer processor disables color writing. Thus color and coverage and ignored and no blending
19  * occurs. This XP is usful for things like stenciling.
20  */
21 class DisableColorXP : public GrXferProcessor {
22 public:
DisableColorXP()23     DisableColorXP() : INHERITED(kDisableColorXP_ClassID) {}
24 
25     SkString getShaderDfxInfo() const override { return SkString("ShaderDfx_DisableColorXP"); }
26 
27 private:
28     const char* name() const override { return "Disable Color"; }
29     bool onIsEqual(const GrXferProcessor& xpBase) const override { return true; }
30     void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
31     void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override {
32         blendInfo->fWriteColor = false;
33     }
34     std::unique_ptr<ProgramImpl> makeProgramImpl() const override;
35 
36     using INHERITED = GrXferProcessor;
37 };
38 
makeProgramImpl() const39 std::unique_ptr<GrXferProcessor::ProgramImpl> DisableColorXP::makeProgramImpl() const {
40     class Impl : public ProgramImpl {
41     private:
42         void emitOutputsForBlendState(const EmitArgs& args) override {
43             if (args.fShaderCaps->mustWriteToFragColor()) {
44                 // This emit code should be empty. However, on the nexus 6 there is a driver bug
45                 // where if you do not give gl_FragColor a value, the gl context is lost and we end
46                 // up drawing nothing. So this fix just sets the gl_FragColor arbitrarily to 0.
47                 // https://bugs.chromium.org/p/chromium/issues/detail?id=445377
48                 GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
49                 fragBuilder->codeAppendf("%s = half4(0);", args.fOutputPrimary);
50             }
51         }
52 
53         void emitWriteSwizzle(GrGLSLXPFragmentBuilder*,
54                               const GrSwizzle&,
55                               const char*,
56                               const char*) const override {
57             // Don't write any swizzling. This makes sure the final shader does not output a color.
58             return;
59         }
60     };
61 
62     return std::make_unique<Impl>();
63 }
64 
MakeXferProcessor()65 sk_sp<const GrXferProcessor> GrDisableColorXPFactory::MakeXferProcessor() {
66     return sk_make_sp<DisableColorXP>();
67 }
68 
69 GR_DEFINE_XP_FACTORY_TEST(GrDisableColorXPFactory);
70 
71 #if GR_TEST_UTILS
TestGet(GrProcessorTestData*)72 const GrXPFactory* GrDisableColorXPFactory::TestGet(GrProcessorTestData*) {
73     return GrDisableColorXPFactory::Get();
74 }
75 #endif
76