blob: 2be07b19d9f76e86bd30d1a5e09188b1d0db6915 [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/GrPrimitiveProcessor.h"
#include "src/gpu/GrCoordTransform.h"
#include "src/gpu/GrFragmentProcessor.h"
/**
* We specialize the vertex or fragment coord transform code for these matrix types, and where
* the transform code is applied.
*/
enum SampleFlag {
kExplicitlySampled_Flag = 0b0000001, // GrFP::isSampledWithExplicitCoords()
kLegacyCoordTransform_Flag = 0b0000010, // !GrFP::coordTransform(i)::isNoOp()
kNone_SampleMatrix_Flag = 0b0000100, // GrFP::sampleMatrix()::isNoOp()
kConstUniform_SampleMatrix_Flag = 0b0001000, // GrFP::sampleMatrix()::isConstUniform()
kVariable_SampleMatrix_Flag = 0b0001100, // GrFP::sampleMatrix()::isVariable()
// Legacy coord transforms specialize on identity, S+T, no-perspective, and general matrix types
// FIXME these (and kLegacyCoordTransform) can be removed once all FPs no longer use them
kLCT_ScaleTranslate_Matrix_Flag = 0b0010000, // GrFP::coordTransform(i)::isScaleTranslate()
kLCT_NoPersp_Matrix_Flag = 0b0100000, // !GrFP::coordTransform(i)::hasPerspective()
kLCT_General_Matrix_Flag = 0b0110000, // any other matrix type
// Currently, sample(matrix) only specializes on no-perspective or general.
// FIXME add new flags as more matrix types are supported.
kPersp_Matrix_Flag = 0b1000000, // GrFP::sampleMatrix()::fHasPerspective
};
GrPrimitiveProcessor::GrPrimitiveProcessor(ClassID classID) : GrProcessor(classID) {}
const GrPrimitiveProcessor::TextureSampler& GrPrimitiveProcessor::textureSampler(int i) const {
SkASSERT(i >= 0 && i < this->numTextureSamplers());
return this->onTextureSampler(i);
}
uint32_t GrPrimitiveProcessor::computeCoordTransformsKey(const GrFragmentProcessor& fp) const {
// This is highly coupled with the code in GrGLSLGeometryProcessor::emitTransforms().
// At this point, all effects either don't use legacy coord transforms, or only use 1.
SkASSERT(fp.numCoordTransforms() <= 1);
uint32_t key = 0;
if (fp.isSampledWithExplicitCoords()) {
key |= kExplicitlySampled_Flag;
}
if (fp.numCoordTransforms() > 0) {
const GrCoordTransform& coordTransform = fp.coordTransform(0);
if (!coordTransform.isNoOp()) {
// A true identity matrix shouldn't result in a coord transform; proxy normalization
// and flipping will eventually present as a scale+translate matrix.
SkASSERT(!coordTransform.matrix().isIdentity() || coordTransform.normalize() ||
coordTransform.reverseY());
key |= kLegacyCoordTransform_Flag;
if (coordTransform.matrix().isScaleTranslate()) {
key |= kLCT_ScaleTranslate_Matrix_Flag;
} else if (!coordTransform.matrix().hasPerspective()) {
key |= kLCT_NoPersp_Matrix_Flag;
} else {
key |= kLCT_General_Matrix_Flag;
}
}
}
switch(fp.sampleMatrix().fKind) {
case SkSL::SampleMatrix::Kind::kNone:
key |= kNone_SampleMatrix_Flag;
break;
case SkSL::SampleMatrix::Kind::kConstantOrUniform:
key |= kConstUniform_SampleMatrix_Flag;
break;
case SkSL::SampleMatrix::Kind::kVariable:
key |= kVariable_SampleMatrix_Flag;
break;
}
if (fp.sampleMatrix().fHasPerspective) {
key |= kPersp_Matrix_Flag;
}
return key;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
static inline GrSamplerState::Filter clamp_filter(GrTextureType type,
GrSamplerState::Filter requestedFilter) {
if (GrTextureTypeHasRestrictedSampling(type)) {
return std::min(requestedFilter, GrSamplerState::Filter::kBilerp);
}
return requestedFilter;
}
GrPrimitiveProcessor::TextureSampler::TextureSampler(GrSamplerState samplerState,
const GrBackendFormat& backendFormat,
const GrSwizzle& swizzle) {
this->reset(samplerState, backendFormat, swizzle);
}
void GrPrimitiveProcessor::TextureSampler::reset(GrSamplerState samplerState,
const GrBackendFormat& backendFormat,
const GrSwizzle& swizzle) {
fSamplerState = samplerState;
fSamplerState.setFilterMode(clamp_filter(backendFormat.textureType(), samplerState.filter()));
fBackendFormat = backendFormat;
fSwizzle = swizzle;
fIsInitialized = true;
}