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 "GrProcessor.h" 10#include "gl/GrGLXferProcessor.h" 11#include "gl/builders/GrGLFragmentShaderBuilder.h" 12#include "gl/builders/GrGLProgramBuilder.h" 13 14/** 15 * This xfer processor disables color writing. Thus color and coverage and ignored and no blending 16 * occurs. This XP is usful for things like stenciling. 17 */ 18class DisableColorXP : public GrXferProcessor { 19public: 20 static GrXferProcessor* Create() { 21 return SkNEW(DisableColorXP); 22 } 23 24 ~DisableColorXP() override {}; 25 26 const char* name() const override { return "Disable Color"; } 27 28 GrGLXferProcessor* createGLInstance() const override; 29 30 bool hasSecondaryOutput() const override { return false; } 31 32private: 33 DisableColorXP(); 34 35 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, 36 const GrProcOptInfo& coveragePOI, 37 bool doesStencilWrite, 38 GrColor* color, 39 const GrDrawTargetCaps& caps) override { 40 return GrXferProcessor::kIgnoreColor_OptFlag | GrXferProcessor::kIgnoreCoverage_OptFlag; 41 } 42 43 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override; 44 45 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override; 46 47 bool onIsEqual(const GrXferProcessor& xpBase) const override { 48 return true; 49 } 50 51 typedef GrXferProcessor INHERITED; 52}; 53 54/////////////////////////////////////////////////////////////////////////////// 55 56class GLDisableColorXP : public GrGLXferProcessor { 57public: 58 GLDisableColorXP(const GrProcessor&) {} 59 60 ~GLDisableColorXP() override {} 61 62 static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*) {} 63 64private: 65 void onEmitCode(const EmitArgs& args) override { 66 // This emit code should be empty. However, on the nexus 6 there is a driver bug where if 67 // you do not give gl_FragColor a value, the gl context is lost and we end up drawing 68 // nothing. So this fix just sets the gl_FragColor arbitrarily to 0. 69 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 70 fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary); 71 } 72 73 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) override {} 74 75 typedef GrGLXferProcessor INHERITED; 76}; 77 78/////////////////////////////////////////////////////////////////////////////// 79 80DisableColorXP::DisableColorXP() { 81 this->initClassID<DisableColorXP>(); 82} 83 84void DisableColorXP::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const { 85 GLDisableColorXP::GenKey(*this, caps, b); 86} 87 88GrGLXferProcessor* DisableColorXP::createGLInstance() const { 89 return SkNEW_ARGS(GLDisableColorXP, (*this)); 90} 91 92void DisableColorXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const { 93 blendInfo->fWriteColor = false; 94} 95 96/////////////////////////////////////////////////////////////////////////////// 97 98GrDisableColorXPFactory::GrDisableColorXPFactory() { 99 this->initClassID<GrDisableColorXPFactory>(); 100} 101 102GrXferProcessor* 103GrDisableColorXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps, 104 const GrProcOptInfo& colorPOI, 105 const GrProcOptInfo& covPOI, 106 const GrDeviceCoordTexture* dstCopy) const { 107 return DisableColorXP::Create(); 108} 109 110GR_DEFINE_XP_FACTORY_TEST(GrDisableColorXPFactory); 111 112GrXPFactory* GrDisableColorXPFactory::TestCreate(SkRandom* random, 113 GrContext*, 114 const GrDrawTargetCaps&, 115 GrTexture*[]) { 116 return GrDisableColorXPFactory::Create(); 117} 118 119