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 private: name() const26 const char* name() const override { return "Disable Color"; } onIsEqual(const GrXferProcessor & xpBase) const27 bool onIsEqual(const GrXferProcessor& xpBase) const override { return true; } onAddToKey(const GrShaderCaps &,GrProcessorKeyBuilder *) const28 void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} onGetBlendInfo(GrXferProcessor::BlendInfo * blendInfo) const29 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { 30 blendInfo->fWriteColor = false; 31 } 32 std::unique_ptr<ProgramImpl> makeProgramImpl() const override; 33 34 using INHERITED = GrXferProcessor; 35 }; 36 makeProgramImpl() const37std::unique_ptr<GrXferProcessor::ProgramImpl> DisableColorXP::makeProgramImpl() const { 38 class Impl : public ProgramImpl { 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 43 // where if you do not give gl_FragColor a value, the gl context is lost and we end 44 // up drawing 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 60 return std::make_unique<Impl>(); 61 } 62 MakeXferProcessor()63sk_sp<const GrXferProcessor> GrDisableColorXPFactory::MakeXferProcessor() { 64 return sk_make_sp<DisableColorXP>(); 65 } 66 67 GR_DEFINE_XP_FACTORY_TEST(GrDisableColorXPFactory); 68 69 #if GR_TEST_UTILS TestGet(GrProcessorTestData *)70const GrXPFactory* GrDisableColorXPFactory::TestGet(GrProcessorTestData*) { 71 return GrDisableColorXPFactory::Get(); 72 } 73 #endif 74