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() const39std::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()65sk_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*)72const GrXPFactory* GrDisableColorXPFactory::TestGet(GrProcessorTestData*) { 73 return GrDisableColorXPFactory::Get(); 74 } 75 #endif 76