1080e673b10ac607305f140ddb245e140ccde40c6egdaniel/*
2080e673b10ac607305f140ddb245e140ccde40c6egdaniel * Copyright 2014 Google Inc.
3080e673b10ac607305f140ddb245e140ccde40c6egdaniel *
4080e673b10ac607305f140ddb245e140ccde40c6egdaniel * Use of this source code is governed by a BSD-style license that can be
5080e673b10ac607305f140ddb245e140ccde40c6egdaniel * found in the LICENSE file.
6080e673b10ac607305f140ddb245e140ccde40c6egdaniel */
7080e673b10ac607305f140ddb245e140ccde40c6egdaniel
8080e673b10ac607305f140ddb245e140ccde40c6egdaniel#include "effects/GrDisableColorXP.h"
9080e673b10ac607305f140ddb245e140ccde40c6egdaniel#include "GrProcessor.h"
10080e673b10ac607305f140ddb245e140ccde40c6egdaniel#include "gl/GrGLXferProcessor.h"
11be9588ade8e3dac0adc8e038c46de006ca21af48egdaniel#include "gl/builders/GrGLFragmentShaderBuilder.h"
12be9588ade8e3dac0adc8e038c46de006ca21af48egdaniel#include "gl/builders/GrGLProgramBuilder.h"
13080e673b10ac607305f140ddb245e140ccde40c6egdaniel
1441d4f09356567ead0216e1a7e4110bd58822b81fegdaniel/**
1541d4f09356567ead0216e1a7e4110bd58822b81fegdaniel * This xfer processor disables color writing. Thus color and coverage and ignored and no blending
1641d4f09356567ead0216e1a7e4110bd58822b81fegdaniel * occurs. This XP is usful for things like stenciling.
1741d4f09356567ead0216e1a7e4110bd58822b81fegdaniel */
1841d4f09356567ead0216e1a7e4110bd58822b81fegdanielclass DisableColorXP : public GrXferProcessor {
1941d4f09356567ead0216e1a7e4110bd58822b81fegdanielpublic:
2041d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    static GrXferProcessor* Create() {
2141d4f09356567ead0216e1a7e4110bd58822b81fegdaniel        return SkNEW(DisableColorXP);
2241d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    }
2341d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
2436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    ~DisableColorXP() override {};
2541d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
2636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "Disable Color"; }
2741d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
2836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    GrGLXferProcessor* createGLInstance() const override;
2941d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
3036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool hasSecondaryOutput() const override { return false; }
3141d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
3241d4f09356567ead0216e1a7e4110bd58822b81fegdanielprivate:
3341d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    DisableColorXP();
3441d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
35c19cdc254cc08f334b00c3b9fdb703818c8ca681egdaniel    GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
36c19cdc254cc08f334b00c3b9fdb703818c8ca681egdaniel                                                 const GrProcOptInfo& coveragePOI,
37c19cdc254cc08f334b00c3b9fdb703818c8ca681egdaniel                                                 bool doesStencilWrite,
38c19cdc254cc08f334b00c3b9fdb703818c8ca681egdaniel                                                 GrColor* color,
39c19cdc254cc08f334b00c3b9fdb703818c8ca681egdaniel                                                 const GrDrawTargetCaps& caps) override {
40c19cdc254cc08f334b00c3b9fdb703818c8ca681egdaniel        return GrXferProcessor::kIgnoreColor_OptFlag | GrXferProcessor::kIgnoreCoverage_OptFlag;
41c19cdc254cc08f334b00c3b9fdb703818c8ca681egdaniel    }
42c19cdc254cc08f334b00c3b9fdb703818c8ca681egdaniel
43cfc18867d982119d9dc2888bf09f1093012daaddjvanverth    void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
4441d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
45f4f2b442228ca188cfb6b44ee3faa86773bb9db3cdalton    void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override;
46f4f2b442228ca188cfb6b44ee3faa86773bb9db3cdalton
4736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onIsEqual(const GrXferProcessor& xpBase) const override {
4841d4f09356567ead0216e1a7e4110bd58822b81fegdaniel        return true;
4941d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    }
5041d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
5141d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    typedef GrXferProcessor INHERITED;
5241d4f09356567ead0216e1a7e4110bd58822b81fegdaniel};
5341d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
5441d4f09356567ead0216e1a7e4110bd58822b81fegdaniel///////////////////////////////////////////////////////////////////////////////
5541d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
5641d4f09356567ead0216e1a7e4110bd58822b81fegdanielclass GLDisableColorXP : public GrGLXferProcessor {
57080e673b10ac607305f140ddb245e140ccde40c6egdanielpublic:
5841d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    GLDisableColorXP(const GrProcessor&) {}
59080e673b10ac607305f140ddb245e140ccde40c6egdaniel
6036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    ~GLDisableColorXP() override {}
61080e673b10ac607305f140ddb245e140ccde40c6egdaniel
62cfc18867d982119d9dc2888bf09f1093012daaddjvanverth    static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*) {}
6350785a3d10b53bea5beb6e18431a2449860be237bsalomon
6450785a3d10b53bea5beb6e18431a2449860be237bsalomonprivate:
6536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onEmitCode(const EmitArgs& args) override {
66be9588ade8e3dac0adc8e038c46de006ca21af48egdaniel        // This emit code should be empty. However, on the nexus 6 there is a driver bug where if
67be9588ade8e3dac0adc8e038c46de006ca21af48egdaniel        // you do not give gl_FragColor a value, the gl context is lost and we end up drawing
68be9588ade8e3dac0adc8e038c46de006ca21af48egdaniel        // nothing. So this fix just sets the gl_FragColor arbitrarily to 0.
6929bee0fe657fabf7c396502b69c9167fba13eaaaegdaniel        GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
70be9588ade8e3dac0adc8e038c46de006ca21af48egdaniel        fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary);
71be9588ade8e3dac0adc8e038c46de006ca21af48egdaniel    }
72080e673b10ac607305f140ddb245e140ccde40c6egdaniel
7336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) override {}
74080e673b10ac607305f140ddb245e140ccde40c6egdaniel
75080e673b10ac607305f140ddb245e140ccde40c6egdaniel    typedef GrGLXferProcessor INHERITED;
76080e673b10ac607305f140ddb245e140ccde40c6egdaniel};
77080e673b10ac607305f140ddb245e140ccde40c6egdaniel
78080e673b10ac607305f140ddb245e140ccde40c6egdaniel///////////////////////////////////////////////////////////////////////////////
79080e673b10ac607305f140ddb245e140ccde40c6egdaniel
8041d4f09356567ead0216e1a7e4110bd58822b81fegdanielDisableColorXP::DisableColorXP() {
8141d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    this->initClassID<DisableColorXP>();
82080e673b10ac607305f140ddb245e140ccde40c6egdaniel}
83080e673b10ac607305f140ddb245e140ccde40c6egdaniel
84cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid DisableColorXP::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
8541d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    GLDisableColorXP::GenKey(*this, caps, b);
86080e673b10ac607305f140ddb245e140ccde40c6egdaniel}
87080e673b10ac607305f140ddb245e140ccde40c6egdaniel
8841d4f09356567ead0216e1a7e4110bd58822b81fegdanielGrGLXferProcessor* DisableColorXP::createGLInstance() const {
8941d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    return SkNEW_ARGS(GLDisableColorXP, (*this));
90080e673b10ac607305f140ddb245e140ccde40c6egdaniel}
91080e673b10ac607305f140ddb245e140ccde40c6egdaniel
92f4f2b442228ca188cfb6b44ee3faa86773bb9db3cdaltonvoid DisableColorXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const {
93080e673b10ac607305f140ddb245e140ccde40c6egdaniel    blendInfo->fWriteColor = false;
94080e673b10ac607305f140ddb245e140ccde40c6egdaniel}
95080e673b10ac607305f140ddb245e140ccde40c6egdaniel
96080e673b10ac607305f140ddb245e140ccde40c6egdaniel///////////////////////////////////////////////////////////////////////////////
97080e673b10ac607305f140ddb245e140ccde40c6egdaniel
98080e673b10ac607305f140ddb245e140ccde40c6egdanielGrDisableColorXPFactory::GrDisableColorXPFactory() {
99080e673b10ac607305f140ddb245e140ccde40c6egdaniel    this->initClassID<GrDisableColorXPFactory>();
100080e673b10ac607305f140ddb245e140ccde40c6egdaniel}
101080e673b10ac607305f140ddb245e140ccde40c6egdaniel
10250785a3d10b53bea5beb6e18431a2449860be237bsalomonGrXferProcessor*
1033ad6570e94965d54871eaea8b314f560b82ca792egdanielGrDisableColorXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps,
1043ad6570e94965d54871eaea8b314f560b82ca792egdaniel                                               const GrProcOptInfo& colorPOI,
10550785a3d10b53bea5beb6e18431a2449860be237bsalomon                                               const GrProcOptInfo& covPOI,
10650785a3d10b53bea5beb6e18431a2449860be237bsalomon                                               const GrDeviceCoordTexture* dstCopy) const {
10741d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    return DisableColorXP::Create();
108080e673b10ac607305f140ddb245e140ccde40c6egdaniel}
109080e673b10ac607305f140ddb245e140ccde40c6egdaniel
110080e673b10ac607305f140ddb245e140ccde40c6egdanielGR_DEFINE_XP_FACTORY_TEST(GrDisableColorXPFactory);
111080e673b10ac607305f140ddb245e140ccde40c6egdaniel
112080e673b10ac607305f140ddb245e140ccde40c6egdanielGrXPFactory* GrDisableColorXPFactory::TestCreate(SkRandom* random,
113080e673b10ac607305f140ddb245e140ccde40c6egdaniel                                                  GrContext*,
114080e673b10ac607305f140ddb245e140ccde40c6egdaniel                                                  const GrDrawTargetCaps&,
115080e673b10ac607305f140ddb245e140ccde40c6egdaniel                                                  GrTexture*[]) {
116080e673b10ac607305f140ddb245e140ccde40c6egdaniel    return GrDisableColorXPFactory::Create();
117080e673b10ac607305f140ddb245e140ccde40c6egdaniel}
118080e673b10ac607305f140ddb245e140ccde40c6egdaniel
119