blob: 81ccb5f5d10ff8cc04abfa138affd7e8aa081329 [file] [log] [blame]
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/GrPipeline.h"
#include "src/gpu/GrProcessor.h"
#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/effects/GrDisableColorXP.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLXferProcessor.h"
/**
* This xfer processor disables color writing. Thus color and coverage and ignored and no blending
* occurs. This XP is usful for things like stenciling.
*/
class DisableColorXP : public GrXferProcessor {
public:
DisableColorXP() : INHERITED(kDisableColorXP_ClassID) {}
private:
const char* name() const override { return "Disable Color"; }
bool onIsEqual(const GrXferProcessor& xpBase) const override { return true; }
void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
return; // No key.
}
void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override {
blendInfo->fWriteColor = false;
}
GrGLSLXferProcessor* createGLSLInstance() const override;
typedef GrXferProcessor INHERITED;
};
class GLDisableColorXP : public GrGLSLXferProcessor {
private:
void emitOutputsForBlendState(const EmitArgs& args) override {
if (args.fShaderCaps->mustWriteToFragColor()) {
// This emit code should be empty. However, on the nexus 6 there is a driver bug where
// if you do not give gl_FragColor a value, the gl context is lost and we end up drawing
// nothing. So this fix just sets the gl_FragColor arbitrarily to 0.
// https://bugs.chromium.org/p/chromium/issues/detail?id=445377
GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
fragBuilder->codeAppendf("%s = half4(0);", args.fOutputPrimary);
}
}
void emitOutputSwizzle(
GrGLSLXPFragmentBuilder*, const GrSwizzle&, const char*, const char*) const override {
// Don't write any swizzling. This makes sure the final shader does not output a color.
return;
}
void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
typedef GrGLSLXferProcessor INHERITED;
};
GrGLSLXferProcessor* DisableColorXP::createGLSLInstance() const {
return new GLDisableColorXP();
}
sk_sp<const GrXferProcessor> GrDisableColorXPFactory::MakeXferProcessor() {
return sk_make_sp<DisableColorXP>();
}
GR_DEFINE_XP_FACTORY_TEST(GrDisableColorXPFactory);
#if GR_TEST_UTILS
const GrXPFactory* GrDisableColorXPFactory::TestGet(GrProcessorTestData*) {
return GrDisableColorXPFactory::Get();
}
#endif