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 "effects/GrDisableColorXP.h" 9 #include "GrPipeline.h" 10 #include "GrProcessor.h" 11 #include "glsl/GrGLSLFragmentShaderBuilder.h" 12 #include "glsl/GrGLSLProgramDataManager.h" 13 #include "glsl/GrGLSLXferProcessor.h" 14 15 /** 16 * This xfer processor disables color writing. Thus color and coverage and ignored and no blending 17 * occurs. This XP is usful for things like stenciling. 18 */ 19 class DisableColorXP : public GrXferProcessor { 20 public: 21 static GrXferProcessor* Create() { return new DisableColorXP; } 22 23 ~DisableColorXP() override {}; 24 25 const char* name() const override { return "Disable Color"; } 26 27 GrGLSLXferProcessor* createGLSLInstance() const override; 28 29 private: 30 DisableColorXP(); 31 32 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations& optimizations, 33 bool doesStencilWrite, 34 GrColor* color, 35 const GrCaps& caps) const override { 36 return GrXferProcessor::kIgnoreColor_OptFlag | GrXferProcessor::kIgnoreCoverage_OptFlag; 37 } 38 39 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override; 40 41 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override; 42 43 bool onIsEqual(const GrXferProcessor& xpBase) const override { 44 return true; 45 } 46 47 typedef GrXferProcessor INHERITED; 48 }; 49 50 /////////////////////////////////////////////////////////////////////////////// 51 52 class GLDisableColorXP : public GrGLSLXferProcessor { 53 public: 54 GLDisableColorXP(const GrProcessor&) {} 55 56 ~GLDisableColorXP() override {} 57 58 static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*) {} 59 60 private: 61 void emitOutputsForBlendState(const EmitArgs& args) override { 62 // This emit code should be empty. However, on the nexus 6 there is a driver bug where if 63 // you do not give gl_FragColor a value, the gl context is lost and we end up drawing 64 // nothing. So this fix just sets the gl_FragColor arbitrarily to 0. 65 GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder; 66 fragBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary); 67 } 68 69 void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {} 70 71 typedef GrGLSLXferProcessor INHERITED; 72 }; 73 74 /////////////////////////////////////////////////////////////////////////////// 75 76 DisableColorXP::DisableColorXP() { 77 this->initClassID<DisableColorXP>(); 78 } 79 80 void DisableColorXP::onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const { 81 GLDisableColorXP::GenKey(*this, caps, b); 82 } 83 84 GrGLSLXferProcessor* DisableColorXP::createGLSLInstance() const { return new GLDisableColorXP(*this); } 85 86 void DisableColorXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const { 87 blendInfo->fWriteColor = false; 88 } 89 90 /////////////////////////////////////////////////////////////////////////////// 91 92 GrDisableColorXPFactory::GrDisableColorXPFactory() { 93 this->initClassID<GrDisableColorXPFactory>(); 94 } 95 96 GrXferProcessor* 97 GrDisableColorXPFactory::onCreateXferProcessor(const GrCaps& caps, 98 const GrPipelineOptimizations& optimizations, 99 bool hasMixedSamples, 100 const DstTexture* dst) const { 101 SkASSERT(!optimizations.fOverrides.fUsePLSDstRead); 102 return DisableColorXP::Create(); 103 } 104 105 GR_DEFINE_XP_FACTORY_TEST(GrDisableColorXPFactory); 106 107 const GrXPFactory* GrDisableColorXPFactory::TestCreate(GrProcessorTestData*) { 108 return GrDisableColorXPFactory::Create(); 109 } 110 111