Chromium Code Reviews| 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() { |