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() const42std::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()67sk_sp<const GrXferProcessor> GrDisableColorXPFactory::MakeXferProcessor() { 68 return sk_make_sp<DisableColorXP>(); 69 } 70 GR_DEFINE_XP_FACTORY_TEST(GrDisableColorXPFactory) const71GR_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