blob: d47f687d8970164f68ebf7629a011b9797a07c4d [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 "GrGeometryProcessor.h"
#include "gl/GrGLGeometryProcessor.h"
#include "GrInvariantOutput.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
void GrGeometryProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) const {
if (fHasVertexColor) {
if (fOpaqueVertexColors) {
out->setUnknownOpaqueFourComponents();
} else {
out->setUnknownFourComponents();
}
} else {
out->setKnownFourComponents(fColor);
}
this->onGetInvariantOutputColor(out);
}
void GrGeometryProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
this->onGetInvariantOutputCoverage(out);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
#include "gl/builders/GrGLProgramBuilder.h"
void GrGLGeometryProcessor::setupColorPassThrough(GrGLGPBuilder* pb,
GrGPInput inputType,
const char* outputName,
const GrGeometryProcessor::GrAttribute* colorAttr,
UniformHandle* colorUniform) {
GrGLGPFragmentBuilder* fs = pb->getFragmentShaderBuilder();
if (kUniform_GrGPInput == inputType) {
SkASSERT(colorUniform);
const char* stagedLocalVarName;
*colorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType,
kDefault_GrSLPrecision,
"Color",
&stagedLocalVarName);
fs->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
} else if (kAttribute_GrGPInput == inputType) {
SkASSERT(colorAttr);
pb->addPassThroughAttribute(colorAttr, outputName);
} else if (kAllOnes_GrGPInput == inputType) {
fs->codeAppendf("%s = vec4(1);", outputName);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
struct PathBatchTracker {
GrGPInput fInputColorType;
GrGPInput fInputCoverageType;
GrColor fColor;
bool fUsesLocalCoords;
};
class GrGLPathProcessor : public GrGLGeometryProcessor {
public:
GrGLPathProcessor(const GrPathProcessor&, const GrBatchTracker&)
: fColor(GrColor_ILLEGAL) {}
void emitCode(const EmitArgs& args) SK_OVERRIDE {
GrGLGPBuilder* pb = args.fPB;
GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
const PathBatchTracker& local = args.fBT.cast<PathBatchTracker>();
// Setup uniform color
if (kUniform_GrGPInput == local.fInputColorType) {
const char* stagedLocalVarName;
fColorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType,
kDefault_GrSLPrecision,
"Color",
&stagedLocalVarName);
fs->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
}
// setup constant solid coverage
if (kAllOnes_GrGPInput == local.fInputCoverageType) {
fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
}
}
static inline void GenKey(const GrPathProcessor&,
const GrBatchTracker& bt,
const GrGLCaps&,
GrProcessorKeyBuilder* b) {
const PathBatchTracker& local = bt.cast<PathBatchTracker>();
b->add32(local.fInputColorType | local.fInputCoverageType << 16);
}
void setData(const GrGLProgramDataManager& pdman,
const GrPrimitiveProcessor& primProc,
const GrBatchTracker& bt) SK_OVERRIDE {
const PathBatchTracker& local = bt.cast<PathBatchTracker>();
if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
GrGLfloat c[4];
GrColorToRGBAFloat(local.fColor, c);
pdman.set4fv(fColorUniform, 1, c);
fColor = local.fColor;
}
}
private:
UniformHandle fColorUniform;
GrColor fColor;
typedef GrGLGeometryProcessor INHERITED;
};
GrPathProcessor::GrPathProcessor(GrColor color, const SkMatrix& localMatrix)
: INHERITED(localMatrix)
, fColor(color) {
this->initClassID<GrPathProcessor>();
}
void GrPathProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) const {
out->setKnownFourComponents(fColor);
}
void GrPathProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
out->setKnownSingleComponent(0xff);
}
void GrPathProcessor::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
PathBatchTracker* local = bt->cast<PathBatchTracker>();
if (init.fColorIgnored) {
local->fInputColorType = kIgnored_GrGPInput;
local->fColor = GrColor_ILLEGAL;
} else {
local->fInputColorType = kUniform_GrGPInput;
local->fColor = GrColor_ILLEGAL == init.fOverrideColor ? this->color() :
init.fOverrideColor;
}
local->fInputCoverageType = init.fCoverageIgnored ? kIgnored_GrGPInput : kAllOnes_GrGPInput;
local->fUsesLocalCoords = init.fUsesLocalCoords;
}
bool GrPathProcessor::canMakeEqual(const GrBatchTracker& m,
const GrPrimitiveProcessor& that,
const GrBatchTracker& t) const {
if (this->classID() != that.classID() || !this->hasSameTextureAccesses(that)) {
return false;
}
const PathBatchTracker& mine = m.cast<PathBatchTracker>();
const PathBatchTracker& theirs = t.cast<PathBatchTracker>();
return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
that, theirs.fUsesLocalCoords) &&
CanCombineOutput(mine.fInputColorType, mine.fColor,
theirs.fInputColorType, theirs.fColor) &&
CanCombineOutput(mine.fInputCoverageType, 0xff,
theirs.fInputCoverageType, 0xff);
}
void GrPathProcessor::getGLProcessorKey(const GrBatchTracker& bt,
const GrGLCaps& caps,
GrProcessorKeyBuilder* b) const {
GrGLPathProcessor::GenKey(*this, bt, caps, b);
}
GrGLGeometryProcessor* GrPathProcessor::createGLInstance(const GrBatchTracker& bt) const {
return SkNEW_ARGS(GrGLPathProcessor, (*this, bt));
}