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