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