Index: src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp |
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp |
index bd0108407f076d5fce9ee45e2dcba8c80939107a..6835466ccfedc8e605c9d5e01ebfbbafd1b972c5 100644 |
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp |
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp |
@@ -66,6 +66,16 @@ GrGLSLFragmentShaderBuilder::KeyForFragmentPosition(const GrRenderTarget* dst) { |
} |
} |
+static const char* sampleOffsetArrays[] = { |
+ "deviceSpaceSampleOffsets", |
+ "windowSpaceSampleOffsets" |
+}; |
+ |
+GR_STATIC_ASSERT(0 == GrGLSLFPFragmentBuilder::kSkiaDevice_Coordinates); |
+GR_STATIC_ASSERT(1 == GrGLSLFPFragmentBuilder::kGLSLWindow_Coordinates); |
+GR_STATIC_ASSERT(SK_ARRAY_COUNT(sampleOffsetArrays) == |
+ GrGLSLFPFragmentBuilder::kLast_Coordinates + 1); |
+ |
GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program, |
uint8_t fragPosKey) |
: GrGLSLFragmentBuilder(program) |
@@ -74,6 +84,7 @@ GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* p |
, fHasCustomColorOutput(false) |
, fCustomColorOutputIndex(-1) |
, fHasSecondaryOutput(false) |
+ , fUsedSampleOffsetArrays(0) |
, fHasInitializedSampleMask(false) { |
fSubstageIndices.push_back(0); |
#ifdef SK_DEBUG |
@@ -82,10 +93,6 @@ GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* p |
#endif |
} |
-bool GrGLSLFragmentShaderBuilder::hasFragmentPosition() const { |
- return 0 != fProgramBuilder->header().fFragPosKey; |
-} |
- |
bool GrGLSLFragmentShaderBuilder::enableFeature(GLSLFeature feature) { |
switch (feature) { |
case kStandardDerivatives_GLSLFeature: { |
@@ -129,7 +136,7 @@ SkString GrGLSLFragmentShaderBuilder::ensureFSCoords2D(const GrGLSLTransformedCo |
} |
const char* GrGLSLFragmentShaderBuilder::fragmentPosition() { |
- SkASSERT(this->hasFragmentPosition()); |
+ SkASSERT(fProgramBuilder->canReadFragmentPosition()); |
SkDEBUGCODE(fUsedProcessorFeatures |= GrProcessor::kFragmentPosition_RequiredFeature;) |
const GrGLSLCaps* glslCaps = fProgramBuilder->glslCaps(); |
@@ -177,6 +184,13 @@ const char* GrGLSLFragmentShaderBuilder::fragmentPosition() { |
} |
} |
+void GrGLSLFragmentShaderBuilder::appendOffsetToSample(const char* sampleIdx, Coordinates coords) { |
+ SkASSERT(fProgramBuilder->canUseSampleLocations()); |
Chris Dalton
2016/02/29 20:52:50
Is an assert here good enough? Or do we prefer an
bsalomon
2016/03/01 14:28:55
An assert seems fine.
|
+ SkDEBUGCODE(fUsedProcessorFeatures |= GrProcessor::kSampleLocations_RequiredFeature); |
+ this->codeAppendf("%s[%s]", sampleOffsetArrays[coords], sampleIdx); |
+ fUsedSampleOffsetArrays |= (1 << coords); |
+} |
+ |
void GrGLSLFragmentShaderBuilder::maskSampleCoverage(const char* mask, bool invert) { |
const GrGLSLCaps& glslCaps = *fProgramBuilder->glslCaps(); |
if (!glslCaps.sampleVariablesSupport()) { |
@@ -313,6 +327,34 @@ void GrGLSLFragmentShaderBuilder::onFinalize() { |
GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, |
*fProgramBuilder->glslCaps(), |
&this->precisionQualifier()); |
+ if (fUsedSampleOffsetArrays & (1 << kSkiaDevice_Coordinates)) { |
+ this->defineSampleOffsetArray(sampleOffsetArrays[kSkiaDevice_Coordinates], |
+ SkMatrix::MakeTrans(-0.5f, -0.5f)); |
+ } |
+ if (fUsedSampleOffsetArrays & (1 << kGLSLWindow_Coordinates)) { |
+ SkMatrix m; |
+ m.setScale(1, -1); |
+ m.preTranslate(-0.5f, -0.5f); |
+ this->defineSampleOffsetArray(sampleOffsetArrays[kGLSLWindow_Coordinates], m); |
+ } |
+} |
+ |
+void GrGLSLFragmentShaderBuilder::defineSampleOffsetArray(const char* name, const SkMatrix& m) { |
+ const GrPipeline& pipeline = fProgramBuilder->pipeline(); |
+ const GrRenderTargetPriv& rtp = pipeline.getRenderTarget()->renderTargetPriv(); |
+ int effectiveSampleCnt = rtp.getEffectiveSampleCount(pipeline.getStencil()); |
+ SkSTArray<16, SkPoint, true> offsets; |
+ offsets.push_back_n(effectiveSampleCnt); |
+ m.mapPoints(offsets.begin(), rtp.getSampleLocations(pipeline.getStencil()), effectiveSampleCnt); |
+ this->definitions().append("const "); |
+ if (fProgramBuilder->glslCaps()->usesPrecisionModifiers()) { |
+ this->definitions().append("highp "); |
+ } |
+ this->definitions().appendf("vec2 %s[] = vec2[](", name); |
+ for (int i = 0; i < effectiveSampleCnt; ++i) { |
+ this->definitions().appendf("vec2(%f, %f)", offsets[i].x(), offsets[i].y()); |
+ this->definitions().append(i + 1 != effectiveSampleCnt ? ", " : ");\n"); |
+ } |
} |
void GrGLSLFragmentShaderBuilder::onBeforeChildProcEmitCode() { |