InstanceProcessor.cpp revision dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1
1a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton/* 2a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * Copyright 2016 Google Inc. 3a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * 4a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * Use of this source code is governed by a BSD-style license that can be 5a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * found in the LICENSE file. 6a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton */ 7a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 8a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "InstanceProcessor.h" 9a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 10a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "GrContext.h" 11a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "GrRenderTargetPriv.h" 12a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "GrResourceCache.h" 13a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "GrResourceProvider.h" 14a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "glsl/GrGLSLGeometryProcessor.h" 15a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "glsl/GrGLSLFragmentShaderBuilder.h" 16a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "glsl/GrGLSLProgramBuilder.h" 17a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#include "glsl/GrGLSLVarying.h" 18a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 19a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonnamespace gr_instanced { 20a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 21a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonbool InstanceProcessor::IsSupported(const GrGLSLCaps& glslCaps, const GrCaps& caps, 22a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton AntialiasMode* lastSupportedAAMode) { 23a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!glslCaps.canUseAnyFunctionInShader() || 24a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton !glslCaps.flatInterpolationSupport() || 25a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton !glslCaps.integerSupport() || 26a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 0 == glslCaps.maxVertexSamplers() || 27a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton !caps.shaderCaps()->texelBufferSupport() || 28a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton caps.maxVertexAttributes() < kNumAttribs) { 29a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return false; 30a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 31a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (caps.sampleLocationsSupport() && 32a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton glslCaps.sampleVariablesSupport() && 33a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton glslCaps.shaderDerivativeSupport()) { 34a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (0 != caps.maxRasterSamples() && 35a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton glslCaps.sampleMaskOverrideCoverageSupport()) { 36a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton *lastSupportedAAMode = AntialiasMode::kMixedSamples; 37a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 38a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton *lastSupportedAAMode = AntialiasMode::kMSAA; 39a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 40a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 41a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton *lastSupportedAAMode = AntialiasMode::kCoverage; 42a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 43a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return true; 44a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 45a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 46a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonInstanceProcessor::InstanceProcessor(BatchInfo batchInfo, GrBuffer* paramsBuffer) 47a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton : fBatchInfo(batchInfo) { 48a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->initClassID<InstanceProcessor>(); 49a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 50a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->addVertexAttrib(Attribute("shapeCoords", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision)); 51a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->addVertexAttrib(Attribute("vertexAttrs", kInt_GrVertexAttribType)); 52a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->addVertexAttrib(Attribute("instanceInfo", kUint_GrVertexAttribType)); 53a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->addVertexAttrib(Attribute("shapeMatrixX", kVec3f_GrVertexAttribType, 54a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision)); 55a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->addVertexAttrib(Attribute("shapeMatrixY", kVec3f_GrVertexAttribType, 56a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision)); 57a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->addVertexAttrib(Attribute("color", kVec4f_GrVertexAttribType, kLow_GrSLPrecision)); 58a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->addVertexAttrib(Attribute("localRect", kVec4f_GrVertexAttribType, kHigh_GrSLPrecision)); 59a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 60a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(0 == (int)Attrib::kShapeCoords); 61a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(1 == (int)Attrib::kVertexAttrs); 62a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(2 == (int)Attrib::kInstanceInfo); 63a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(3 == (int)Attrib::kShapeMatrixX); 64a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(4 == (int)Attrib::kShapeMatrixY); 65a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(5 == (int)Attrib::kColor); 66a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(6 == (int)Attrib::kLocalRect); 67a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(7 == kNumAttribs); 68a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 69a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBatchInfo.fHasParams) { 70a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(paramsBuffer); 71a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fParamsAccess.reset(kRGBA_float_GrPixelConfig, paramsBuffer, kVertex_GrShaderFlag); 72a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->addBufferAccess(&fParamsAccess); 73a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 74a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 75a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBatchInfo.fAntialiasMode >= AntialiasMode::kMSAA) { 76a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fBatchInfo.isSimpleRects() || 77a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton AntialiasMode::kMixedSamples == fBatchInfo.fAntialiasMode) { 78a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->setWillUseSampleLocations(); 79a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 80a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 81a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 82a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 83a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor : public GrGLSLGeometryProcessor { 84a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic: 85a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override; 86a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 87a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate: 88a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) override {} 89a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 90a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton class VertexInputs; 91a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton class Backend; 92a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton class BackendNonAA; 93a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton class BackendCoverage; 94a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton class BackendMultisample; 95a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 96a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton typedef GrGLSLGeometryProcessor INHERITED; 97a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 98a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 99a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGrGLSLPrimitiveProcessor* InstanceProcessor::createGLSLInstance(const GrGLSLCaps&) const { 100a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return new GLSLInstanceProcessor(); 101a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 102a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 103a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::VertexInputs { 104a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic: 105a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton VertexInputs(const InstanceProcessor& instProc, GrGLSLVertexBuilder* vertexBuilder) 106a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton : fInstProc(instProc), 107a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fVertexBuilder(vertexBuilder) { 108a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 109a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 110a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void initParams(const SamplerHandle paramsBuffer) { 111a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fParamsBuffer = paramsBuffer; 112a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fVertexBuilder->definef("PARAMS_IDX_MASK", "0x%xu", kParamsIdx_InfoMask); 113a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fVertexBuilder->appendPrecisionModifier(kHigh_GrSLPrecision); 114a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fVertexBuilder->codeAppendf("int paramsIdx = int(%s & PARAMS_IDX_MASK);", 115a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->attr(Attrib::kInstanceInfo)); 116a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 117a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 118a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* attr(Attrib attr) const { return fInstProc.getAttrib((int)attr).fName; } 119a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 120a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void fetchNextParam(GrSLType type = kVec4f_GrSLType) const { 121a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(fParamsBuffer.isValid()); 122a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (type != kVec4f_GrSLType) { 123a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fVertexBuilder->codeAppendf("%s(", GrGLSLTypeString(type)); 124a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 125a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fVertexBuilder->appendTexelFetch(fParamsBuffer, "paramsIdx++"); 126a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (type != kVec4f_GrSLType) { 127a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fVertexBuilder->codeAppend(")"); 128a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 129a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 130a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 131a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void skipParams(unsigned n) const { 132a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(fParamsBuffer.isValid()); 133a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fVertexBuilder->codeAppendf("paramsIdx += %u;", n); 134a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 135a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 136a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate: 137a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const InstanceProcessor& fInstProc; 138a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* fVertexBuilder; 139a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SamplerHandle fParamsBuffer; 140a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 141a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 142a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::Backend { 143a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic: 144a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton static Backend* SK_WARN_UNUSED_RESULT Create(const GrPipeline&, BatchInfo, const VertexInputs&); 145a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual ~Backend() {} 146a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 147a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void init(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*); 148a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void setupRect(GrGLSLVertexBuilder*) = 0; 149a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void setupOval(GrGLSLVertexBuilder*) = 0; 1500caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton void setupRRect(GrGLSLVertexBuilder*, int* usedShapeDefinitions); 151a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 152a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void initInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*); 153a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void setupInnerRect(GrGLSLVertexBuilder*) = 0; 154a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void setupInnerOval(GrGLSLVertexBuilder*) = 0; 1550caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton void setupInnerSimpleRRect(GrGLSLVertexBuilder*); 156a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 157a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outShapeCoords() { 158a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return fModifiedShapeCoords ? fModifiedShapeCoords : fInputs.attr(Attrib::kShapeCoords); 159a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 160a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 161a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char* outCoverage, 162a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outColor); 163a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 164a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprotected: 165a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton Backend(BatchInfo batchInfo, const VertexInputs& inputs) 166a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton : fBatchInfo(batchInfo), 167a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs(inputs), 168a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiesCoverage(false), 169a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiesColor(false), 170a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fNeedsNeighborRadii(false), 171a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fColor(kVec4f_GrSLType), 172a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fTriangleIsArc(kInt_GrSLType), 173a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcCoords(kVec2f_GrSLType), 174a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeCoords(kVec2f_GrSLType), 175a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerRRect(kVec4f_GrSLType), 176a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiedShapeCoords(nullptr) { 177a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBatchInfo.fShapeTypes & kRRect_ShapesMask) { 178a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiedShapeCoords = "adjustedShapeCoords"; 179a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 180a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 181a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 182a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) = 0; 183a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void adjustRRectVertices(GrGLSLVertexBuilder*); 184a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void onSetupRRect(GrGLSLVertexBuilder*) {} 185a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 186a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) = 0; 1870caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton virtual void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) = 0; 188a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 189a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, 190a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage, const char* outColor) = 0; 191a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 192a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupSimpleRadii(GrGLSLVertexBuilder*); 193a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupNinePatchRadii(GrGLSLVertexBuilder*); 194a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupComplexRadii(GrGLSLVertexBuilder*); 195a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 196a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const BatchInfo fBatchInfo; 197a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const VertexInputs& fInputs; 198a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fModifiesCoverage; 199a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fModifiesColor; 200a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fNeedsNeighborRadii; 201a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fColor; 202a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fTriangleIsArc; 203a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fArcCoords; 204a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fInnerShapeCoords; 205a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fInnerRRect; 206a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* fModifiedShapeCoords; 207a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 208a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 209a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { 210a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const GrPipeline& pipeline = args.fVertBuilder->getProgramBuilder()->pipeline(); 211a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const InstanceProcessor& ip = args.fGP.cast<InstanceProcessor>(); 212a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLUniformHandler* uniHandler = args.fUniformHandler; 213a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; 214a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v = args.fVertBuilder; 215a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLPPFragmentBuilder* f = args.fFragBuilder; 216a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 217a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->emitAttributes(ip); 218a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 219a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton VertexInputs inputs(ip, v); 220a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (ip.batchInfo().fHasParams) { 221a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(1 == ip.numBuffers()); 222a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.initParams(args.fBufferSamplers[0]); 223a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 224a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 225a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!ip.batchInfo().fHasPerspective) { 226a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("mat2x3 shapeMatrix = mat2x3(%s, %s);", 227a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY)); 228a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 229a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->definef("PERSPECTIVE_FLAG", "0x%xu", kPerspective_InfoFlag); 230a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("mat3 shapeMatrix = mat3(%s, %s, vec3(0, 0, 1));", 231a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY)); 232a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (0u != (%s & PERSPECTIVE_FLAG)) {", 233a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kInstanceInfo)); 234a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( "shapeMatrix[2] = "); 235a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.fetchNextParam(kVec3f_GrSLType); 236a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( ";"); 237a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("}"); 238a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 239a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 240a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool hasSingleShapeType = SkIsPow2(ip.batchInfo().fShapeTypes); 241a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!hasSingleShapeType) { 242a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->define("SHAPE_TYPE_BIT", kShapeType_InfoBit); 243a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("uint shapeType = %s >> SHAPE_TYPE_BIT;", 244a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kInstanceInfo)); 245a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 246a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 247a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkAutoTDelete<Backend> backend(Backend::Create(pipeline, ip.batchInfo(), inputs)); 248a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->init(varyingHandler, v); 249a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2500caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton int usedShapeDefinitions = 0; 2510caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton 2520caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (hasSingleShapeType || !(ip.batchInfo().fShapeTypes & ~kRRect_ShapesMask)) { 253a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kRect_ShapeFlag == ip.batchInfo().fShapeTypes) { 254a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->setupRect(v); 255a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (kOval_ShapeFlag == ip.batchInfo().fShapeTypes) { 256a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->setupOval(v); 257a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 2580caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton backend->setupRRect(v, &usedShapeDefinitions); 259a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 260a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 2610caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (ip.batchInfo().fShapeTypes & kRRect_ShapesMask) { 2620caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("if (shapeType >= SIMPLE_R_RECT_SHAPE_TYPE) {"); 2630caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton backend->setupRRect(v, &usedShapeDefinitions); 2640caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("}"); 2650caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton usedShapeDefinitions |= kSimpleRRect_ShapeFlag; 266a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 267a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (ip.batchInfo().fShapeTypes & kOval_ShapeFlag) { 2680caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (ip.batchInfo().fShapeTypes & kRect_ShapeFlag) { 2690caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (ip.batchInfo().fShapeTypes & kRRect_ShapesMask) { 2700caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else "); 2710caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 2720caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("if (OVAL_SHAPE_TYPE == shapeType) {"); 2730caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton usedShapeDefinitions |= kOval_ShapeFlag; 2740caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } else { 2750caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else {"); 2760caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 277a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->setupOval(v); 2780caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("}"); 279a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 2800caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (ip.batchInfo().fShapeTypes & kRect_ShapeFlag) { 2810caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else {"); 2820caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton backend->setupRect(v); 2830caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("}"); 284a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 285a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 286a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 287a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (ip.batchInfo().fInnerShapeTypes) { 288a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool hasSingleInnerShapeType = SkIsPow2(ip.batchInfo().fInnerShapeTypes); 289a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!hasSingleInnerShapeType) { 290a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->definef("INNER_SHAPE_TYPE_MASK", "0x%xu", kInnerShapeType_InfoMask); 291a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->define("INNER_SHAPE_TYPE_BIT", kInnerShapeType_InfoBit); 292a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("uint innerShapeType = ((%s & INNER_SHAPE_TYPE_MASK) >> " 293a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "INNER_SHAPE_TYPE_BIT);", 294a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kInstanceInfo)); 295a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 296a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Here we take advantage of the fact that outerRect == localRect in recordDRRect. 297a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec4 outer = %s;", inputs.attr(Attrib::kLocalRect)); 298a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec4 inner = "); 299a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.fetchNextParam(); 300a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend (";"); 301a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // outer2Inner is a transform from shape coords to inner shape coords: 302a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // e.g. innerShapeCoords = shapeCoords * outer2Inner.xy + outer2Inner.zw 303a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec4 outer2Inner = vec4(outer.zw - outer.xy, " 304a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "outer.xy + outer.zw - inner.xy - inner.zw) / " 305a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "(inner.zw - inner.xy).xyxy;"); 306a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 innerShapeCoords = %s * outer2Inner.xy + outer2Inner.zw;", 307a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->outShapeCoords()); 308a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 309a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->initInnerShape(varyingHandler, v); 310a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 3110caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton SkASSERT(0 == (ip.batchInfo().fInnerShapeTypes & kRRect_ShapesMask) || 3120caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton kSimpleRRect_ShapeFlag == (ip.batchInfo().fInnerShapeTypes & kRRect_ShapesMask)); 3130caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton 314a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (hasSingleInnerShapeType) { 315a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kRect_ShapeFlag == ip.batchInfo().fInnerShapeTypes) { 316a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->setupInnerRect(v); 317a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (kOval_ShapeFlag == ip.batchInfo().fInnerShapeTypes) { 318a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->setupInnerOval(v); 319a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 3200caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton backend->setupInnerSimpleRRect(v); 321a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 322a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 3230caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (ip.batchInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) { 3240caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == innerShapeType) {"); 3250caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton backend->setupInnerSimpleRRect(v); 3260caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend("}"); 3270caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton usedShapeDefinitions |= kSimpleRRect_ShapeFlag; 328a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 329a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (ip.batchInfo().fInnerShapeTypes & kOval_ShapeFlag) { 3300caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (ip.batchInfo().fInnerShapeTypes & kRect_ShapeFlag) { 3310caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (ip.batchInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) { 3320caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else "); 3330caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 3340caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("if (OVAL_SHAPE_TYPE == innerShapeType) {"); 3350caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton usedShapeDefinitions |= kOval_ShapeFlag; 3360caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } else { 3370caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else {"); 3380caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 339a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->setupInnerOval(v); 3400caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend("}"); 341a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 3420caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (ip.batchInfo().fInnerShapeTypes & kRect_ShapeFlag) { 3430caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend("else {"); 3440caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton backend->setupInnerRect(v); 3450caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend("}"); 346a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 347a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 348a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 349a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 3500caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (usedShapeDefinitions & kOval_ShapeFlag) { 351a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->definef("OVAL_SHAPE_TYPE", "%du", (int)ShapeType::kOval); 352a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 3530caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (usedShapeDefinitions & kSimpleRRect_ShapeFlag) { 3540caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->definef("SIMPLE_R_RECT_SHAPE_TYPE", "%du", (int)ShapeType::kSimpleRRect); 3550caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 3560caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (usedShapeDefinitions & kNinePatch_ShapeFlag) { 3570caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->definef("NINE_PATCH_SHAPE_TYPE", "%du", (int)ShapeType::kNinePatch); 3580caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 3590caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton SkASSERT(!(usedShapeDefinitions & (kRect_ShapeFlag | kComplexRRect_ShapeFlag))); 360a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 361a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->emitCode(v, f, pipeline.ignoresCoverage() ? nullptr : args.fOutputCoverage, 362a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton args.fOutputColor); 363a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 364a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* localCoords = nullptr; 365a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (ip.batchInfo().fUsesLocalCoords) { 366a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton localCoords = "localCoords"; 367a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 t = 0.5 * (%s + vec2(1));", backend->outShapeCoords()); 368a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 localCoords = (1.0 - t) * %s.xy + t * %s.zw;", 369a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kLocalRect), inputs.attr(Attrib::kLocalRect)); 370a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 371a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (ip.batchInfo().fHasLocalMatrix && ip.batchInfo().fHasParams) { 372a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->definef("LOCAL_MATRIX_FLAG", "0x%xu", kLocalMatrix_InfoFlag); 373a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (0u != (%s & LOCAL_MATRIX_FLAG)) {", 374a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kInstanceInfo)); 375a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!ip.batchInfo().fUsesLocalCoords) { 376a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.skipParams(2); 377a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 378a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf( "mat2x3 localMatrix;"); 379a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( "localMatrix[0] = "); 380a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.fetchNextParam(kVec3f_GrSLType); 381a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( ";"); 382a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( "localMatrix[1] = "); 383a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.fetchNextParam(kVec3f_GrSLType); 384a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( ";"); 385a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( "localCoords = (vec3(localCoords, 1) * localMatrix).xy;"); 386a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 387a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("}"); 388a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 389a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 390a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrSLType positionType = ip.batchInfo().fHasPerspective ? kVec3f_GrSLType : kVec2f_GrSLType; 391a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s deviceCoords = vec3(%s, 1) * shapeMatrix;", 392a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLTypeString(positionType), backend->outShapeCoords()); 393a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton gpArgs->fPositionVar.set(positionType, "deviceCoords"); 394a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 395a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitTransforms(v, varyingHandler, uniHandler, gpArgs->fPositionVar, localCoords, 396a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton args.fTransformsIn, args.fTransformsOut); 397a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 398a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 399a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton//////////////////////////////////////////////////////////////////////////////////////////////////// 400a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 401a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::init(GrGLSLVaryingHandler* varyingHandler, 402a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v) { 403a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fModifiedShapeCoords) { 404a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 %s = %s;", fModifiedShapeCoords, fInputs.attr(Attrib::kShapeCoords)); 405a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 406a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 407a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->onInit(varyingHandler, v); 408a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 409a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fColor.vsOut()) { 410a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("color", &fColor, kLow_GrSLPrecision); 411a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s;", fColor.vsOut(), fInputs.attr(Attrib::kColor)); 412a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 413a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 414a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 4150caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::Backend::setupRRect(GrGLSLVertexBuilder* v, int* usedShapeDefinitions) { 416a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("uvec2 corner = uvec2(%s & 1, (%s >> 1) & 1);", 417a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kVertexAttrs), fInputs.attr(Attrib::kVertexAttrs)); 418a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 cornerSign = vec2(corner) * 2.0 - 1.0;"); 419a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 radii%s;", fNeedsNeighborRadii ? ", neighborRadii" : ""); 420a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("mat2 p = "); 421a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.fetchNextParam(kMat22f_GrSLType); 422a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend (";"); 423a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton uint8_t types = fBatchInfo.fShapeTypes & kRRect_ShapesMask; 424a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (0 == (types & (types - 1))) { 425a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kSimpleRRect_ShapeFlag == types) { 426a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->setupSimpleRadii(v); 427a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (kNinePatch_ShapeFlag == types) { 428a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->setupNinePatchRadii(v); 429a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (kComplexRRect_ShapeFlag == types) { 430a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->setupComplexRadii(v); 431a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 432a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 433a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (types & kSimpleRRect_ShapeFlag) { 4340caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == shapeType) {"); 435a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->setupSimpleRadii(v); 4360caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("}"); 4370caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton *usedShapeDefinitions |= kSimpleRRect_ShapeFlag; 438a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 439a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (types & kNinePatch_ShapeFlag) { 4400caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (types & kComplexRRect_ShapeFlag) { 4410caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (types & kSimpleRRect_ShapeFlag) { 4420caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else "); 4430caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 4440caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("if (NINE_PATCH_SHAPE_TYPE == shapeType) {"); 4450caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton *usedShapeDefinitions |= kNinePatch_ShapeFlag; 4460caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } else { 4470caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else {"); 4480caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 449a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->setupNinePatchRadii(v); 4500caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("}"); 451a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 452a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (types & kComplexRRect_ShapeFlag) { 4530caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else {"); 454a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->setupComplexRadii(v); 4550caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("}"); 456a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 457a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 458a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 459a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->adjustRRectVertices(v); 460a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 461a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fArcCoords.vsOut()) { 462a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = (cornerSign * %s + radii - vec2(1)) / radii;", 463a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcCoords.vsOut(), fModifiedShapeCoords); 464a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 465a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.vsOut()) { 466a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = int(all(equal(vec2(1), abs(%s))));", 467a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kShapeCoords)); 468a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 469a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 470a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->onSetupRRect(v); 471a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 472a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 473a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::setupSimpleRadii(GrGLSLVertexBuilder* v) { 474a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fNeedsNeighborRadii) { 475a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("neighborRadii = "); 476a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 477a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("radii = p[0] * 2.0 / p[1];"); 478a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 479a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 480a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::setupNinePatchRadii(GrGLSLVertexBuilder* v) { 481a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("radii = vec2(p[0][corner.x], p[1][corner.y]);"); 482a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fNeedsNeighborRadii) { 483a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("neighborRadii = vec2(p[0][1u - corner.x], p[1][1u - corner.y]);"); 484a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 485a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 486a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 487a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::setupComplexRadii(GrGLSLVertexBuilder* v) { 488a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton /** 489a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * The x and y radii of each arc are stored in separate vectors, 490a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * in the following order: 491a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * 492a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * __x1 _ _ _ x3__ 493a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * 494a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * y1 | | y2 495a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * 496a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * | | 497a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * 498a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * y3 |__ _ _ _ __| y4 499a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * x2 x4 500a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * 501a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton */ 502a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("mat2 p2 = "); 503a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.fetchNextParam(kMat22f_GrSLType); 504a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend(";"); 505a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("radii = vec2(p[corner.x][corner.y], p2[corner.y][corner.x]);"); 506a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fNeedsNeighborRadii) { 507a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("neighborRadii = vec2(p[1u - corner.x][corner.y], " 508a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "p2[1u - corner.y][corner.x]);"); 509a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 510a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 511a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 512a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::adjustRRectVertices(GrGLSLVertexBuilder* v) { 513a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Resize the 4 triangles that arcs are drawn into so they match their corresponding radii. 514a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // 0.5 is a special value that indicates the edge of an arc triangle. 515a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.x) == 0.5)" 516a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "%s.x = cornerSign.x * (1.0 - radii.x);", 517a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords); 518a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.y) == 0.5) " 519a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "%s.y = cornerSign.y * (1.0 - radii.y);", 520a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords); 521a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 522a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 523a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::initInnerShape(GrGLSLVaryingHandler* varyingHandler, 524a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v) { 525a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!(fBatchInfo.fInnerShapeTypes & (kNinePatch_ShapeFlag | kComplexRRect_ShapeFlag))); 526a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 527a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->onInitInnerShape(varyingHandler, v); 528a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 529a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerShapeCoords.vsOut()) { 530a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = innerShapeCoords;", fInnerShapeCoords.vsOut()); 531a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 532a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 533a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 5340caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::Backend::setupInnerSimpleRRect(GrGLSLVertexBuilder* v) { 535a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("mat2 innerP = "); 536a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.fetchNextParam(kMat22f_GrSLType); 537a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend(";"); 538a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("vec2 innerRadii = innerP[0] * 2.0 / innerP[1];"); 5390caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton this->onSetupInnerSimpleRRect(v); 540a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 541a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 542a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::emitCode(GrGLSLVertexBuilder* v, GrGLSLPPFragmentBuilder* f, 543a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage, const char* outColor) { 544a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!fModifiesCoverage || outCoverage); 545a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->onEmitCode(v, f, fModifiesCoverage ? outCoverage : nullptr, 546a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiesColor ? outColor : nullptr); 547a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (outCoverage && !fModifiesCoverage) { 548a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Even though the subclass doesn't use coverage, we are expected to assign some value. 549a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = vec4(1);", outCoverage); 550a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 551a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fModifiesColor) { 552a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The subclass didn't assign a value to the output color. 553a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = %s;", outColor, fColor.fsIn()); 554a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 555a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 556a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 557a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton//////////////////////////////////////////////////////////////////////////////////////////////////// 558a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 559a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::BackendNonAA : public Backend { 560a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic: 561a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton BackendNonAA(BatchInfo batchInfo, const VertexInputs& inputs) 562a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton : INHERITED(batchInfo, inputs) { 563a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBatchInfo.fCannotDiscard && !fBatchInfo.isSimpleRects()) { 564a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiesColor = !fBatchInfo.fCannotTweakAlphaForCoverage; 565a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiesCoverage = !fModifiesColor; 566a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 567a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 568a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 569a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate: 570a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override; 571a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupRect(GrGLSLVertexBuilder*) override; 572a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupOval(GrGLSLVertexBuilder*) override; 573a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 574a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override; 575a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupInnerRect(GrGLSLVertexBuilder*) override; 576a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupInnerOval(GrGLSLVertexBuilder*) override; 5770caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override; 578a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 579a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char*, 580a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char*) override; 581a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 582a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton typedef Backend INHERITED; 583a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 584a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 585a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onInit(GrGLSLVaryingHandler* varyingHandler, 586a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder*) { 587a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) { 588dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision); 589a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("arcCoords", &fArcCoords, kMedium_GrSLPrecision); 590a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 591a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 592a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 593a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupRect(GrGLSLVertexBuilder* v) { 594a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.vsOut()) { 595a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut()); 596a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 597a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 598a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 599a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupOval(GrGLSLVertexBuilder* v) { 600a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(fArcCoords.vsOut()); 601a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(fTriangleIsArc.vsOut()); 602a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s;", fArcCoords.vsOut(), this->outShapeCoords()); 603a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s & 1;", fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs)); 604a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 605a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 606a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler, 607a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder*) { 608a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords, kMedium_GrSLPrecision); 609a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kRect_ShapeFlag != fBatchInfo.fInnerShapeTypes && 610a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kOval_ShapeFlag != fBatchInfo.fInnerShapeTypes) { 611a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kMedium_GrSLPrecision); 612a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 613a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 614a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 615a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupInnerRect(GrGLSLVertexBuilder* v) { 616a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerRRect.vsOut()) { 617a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(1);", fInnerRRect.vsOut()); 618a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 619a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 620a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 621a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupInnerOval(GrGLSLVertexBuilder* v) { 622a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerRRect.vsOut()) { 623a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(0, 0, 1, 1);", fInnerRRect.vsOut()); 624a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 625a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 626a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 6270caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) { 628a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(1.0 - innerRadii, 1.0 / innerRadii);", fInnerRRect.vsOut()); 629a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 630a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 631a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onEmitCode(GrGLSLVertexBuilder*, 632a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLPPFragmentBuilder* f, 633a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage, 634a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outColor) { 635a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* dropFragment = nullptr; 636a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fBatchInfo.fCannotDiscard) { 637a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton dropFragment = "discard"; 638a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fModifiesCoverage) { 639a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kLow_GrSLPrecision); 640a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("float covered = 1.0;"); 641a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton dropFragment = "covered = 0.0"; 642a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fModifiesColor) { 643a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kLow_GrSLPrecision); 644a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("vec4 color = %s;", fColor.fsIn()); 645a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton dropFragment = "color = vec4(0)"; 646a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 647a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.fsIn()) { 648a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(dropFragment); 649a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s != 0 && dot(%s, %s) > 1.0) %s;", 650a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fTriangleIsArc.fsIn(), fArcCoords.fsIn(), fArcCoords.fsIn(), dropFragment); 651a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 652a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBatchInfo.fInnerShapeTypes) { 653a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(dropFragment); 654a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("// Inner shape.\n"); 655a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kRect_ShapeFlag == fBatchInfo.fInnerShapeTypes) { 656a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (all(lessThanEqual(abs(%s), vec2(1)))) %s;", 657a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeCoords.fsIn(), dropFragment); 658a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (kOval_ShapeFlag == fBatchInfo.fInnerShapeTypes) { 659a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if ((dot(%s, %s) <= 1.0)) %s;", 660a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeCoords.fsIn(), fInnerShapeCoords.fsIn(), dropFragment); 661a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 662a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (all(lessThan(abs(%s), vec2(1)))) {", fInnerShapeCoords.fsIn()); 663a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "vec2 distanceToArcEdge = abs(%s) - %s.xy;", 664a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeCoords.fsIn(), fInnerRRect.fsIn()); 665a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "if (any(lessThan(distanceToArcEdge, vec2(0)))) {"); 666a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "%s;", dropFragment); 667a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "} else {"); 668a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "vec2 rrectCoords = distanceToArcEdge * %s.zw;", 669a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerRRect.fsIn()); 670a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "if (dot(rrectCoords, rrectCoords) <= 1.0) {"); 671a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "%s;", dropFragment); 672a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "}"); 673a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "}"); 674a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 675a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 676a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 677a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fModifiesCoverage) { 678a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = vec4(covered);", outCoverage); 679a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fModifiesColor) { 680a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = color;", outColor); 681a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 682a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 683a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 684a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton//////////////////////////////////////////////////////////////////////////////////////////////////// 685a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 686a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::BackendCoverage : public Backend { 687a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic: 688a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton BackendCoverage(BatchInfo batchInfo, const VertexInputs& inputs) 689a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton : INHERITED(batchInfo, inputs), 690a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fColorTimesRectCoverage(kVec4f_GrSLType), 691a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fRectCoverage(kFloat_GrSLType), 692a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fEllipseCoords(kVec2f_GrSLType), 693a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fEllipseName(kVec2f_GrSLType), 694a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fBloatedRadius(kFloat_GrSLType), 695a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fDistanceToInnerEdge(kVec2f_GrSLType), 696a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeBloatedHalfSize(kVec2f_GrSLType), 697a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerEllipseCoords(kVec2f_GrSLType), 698a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerEllipseName(kVec2f_GrSLType) { 699a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fShapeIsCircle = !fBatchInfo.fNonSquare && !(fBatchInfo.fShapeTypes & kRRect_ShapesMask); 700a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fTweakAlphaForCoverage = !fBatchInfo.fCannotTweakAlphaForCoverage && 701a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton !fBatchInfo.fInnerShapeTypes; 702a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiesCoverage = !fTweakAlphaForCoverage; 703a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiesColor = fTweakAlphaForCoverage; 704a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiedShapeCoords = "bloatedShapeCoords"; 705a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 706a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 707a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate: 708a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override; 709a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupRect(GrGLSLVertexBuilder*) override; 710a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupOval(GrGLSLVertexBuilder*) override; 711a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void adjustRRectVertices(GrGLSLVertexBuilder*) override; 712a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onSetupRRect(GrGLSLVertexBuilder*) override; 713a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 714a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override; 715a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupInnerRect(GrGLSLVertexBuilder*) override; 716a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupInnerOval(GrGLSLVertexBuilder*) override; 7170caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override; 718a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 719a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char* outCoverage, 720a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outColor) override; 721a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 722a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitRect(GrGLSLPPFragmentBuilder*, const char* outCoverage, const char* outColor); 723a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitCircle(GrGLSLPPFragmentBuilder*, const char* outCoverage); 724a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitArc(GrGLSLPPFragmentBuilder* f, const char* ellipseCoords, const char* ellipseName, 725a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool ellipseCoordsNeedClamp, bool ellipseCoordsMayBeNegative, 726a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage); 727a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitInnerRect(GrGLSLPPFragmentBuilder*, const char* outCoverage); 728a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 729a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fColorTimesRectCoverage; 730a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fRectCoverage; 731a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fEllipseCoords; 732a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fEllipseName; 733a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fBloatedRadius; 734a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fDistanceToInnerEdge; 735a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fInnerShapeBloatedHalfSize; 736a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fInnerEllipseCoords; 737a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fInnerEllipseName; 738a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fShapeIsCircle; 739a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fTweakAlphaForCoverage; 740a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 741a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton typedef Backend INHERITED; 742a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 743a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 744a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onInit(GrGLSLVaryingHandler* varyingHandler, 745a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v) { 746a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("mat2 shapeTransposeMatrix = transpose(mat2(shapeMatrix));"); 747a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 shapeHalfSize = vec2(length(shapeTransposeMatrix[0]), " 748a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "length(shapeTransposeMatrix[1]));"); 749a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 bloat = 0.5 / shapeHalfSize;"); 750a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("bloatedShapeCoords = %s * (1.0 + bloat);", fInputs.attr(Attrib::kShapeCoords)); 751a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 752a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kOval_ShapeFlag != fBatchInfo.fShapeTypes) { 753a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTweakAlphaForCoverage) { 754a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("colorTimesRectCoverage", &fColorTimesRectCoverage, 755a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kLow_GrSLPrecision); 756a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kRect_ShapeFlag == fBatchInfo.fShapeTypes) { 757a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fColor = fColorTimesRectCoverage; 758a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 759a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 760a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("rectCoverage", &fRectCoverage, kLow_GrSLPrecision); 761a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 762a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("float rectCoverage = 0.0;"); 763a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 764a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) { 765dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision); 766a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fShapeIsCircle) { 767dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addVarying("ellipseCoords", &fEllipseCoords, kMedium_GrSLPrecision); 768a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("ellipseName", &fEllipseName, kHigh_GrSLPrecision); 769a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 770a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("circleCoords", &fEllipseCoords, kMedium_GrSLPrecision); 771a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("bloatedRadius", &fBloatedRadius, kMedium_GrSLPrecision); 772a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 773a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 774a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 775a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 776a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupRect(GrGLSLVertexBuilder* v) { 777a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Make the border one pixel wide. Inner vs outer is indicated by coordAttrs. 778a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 rectBloat = (%s != 0) ? bloat : -bloat;", 779a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kVertexAttrs)); 780a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Here we use the absolute value, because when the rect is thinner than a pixel, this makes it 781a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // mark the spot where pixel center is within half a pixel of the *opposite* edge. This, 782a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // combined with the "maxCoverage" logic below gives us mathematically correct coverage even for 783a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // subpixel rectangles. 784a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("bloatedShapeCoords = %s * abs(vec2(1.0 + rectBloat));", 785a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords)); 786a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 787a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Determine coverage at the vertex. Coverage naturally ramps from 0 to 1 unless the rect is 788a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // narrower than a pixel. 789a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("float maxCoverage = 4.0 * min(0.5, shapeHalfSize.x) *" 790a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "min(0.5, shapeHalfSize.y);"); 791a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("rectCoverage = (%s != 0) ? 0.0 : maxCoverage;", 792a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kVertexAttrs)); 793a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 794a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.vsOut()) { 795a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut()); 796a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 797a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 798a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 799a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupOval(GrGLSLVertexBuilder* v) { 800a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Offset the inner and outer octagons by one pixel. Inner vs outer is indicated by coordAttrs. 801a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 ovalBloat = (%s != 0) ? bloat : -bloat;", 802a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kVertexAttrs)); 803a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("bloatedShapeCoords = %s * max(vec2(1.0 + ovalBloat), vec2(0));", 804a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords)); 805a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = bloatedShapeCoords * shapeHalfSize;", fEllipseCoords.vsOut()); 806a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fEllipseName.vsOut()) { 807a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 1.0 / (shapeHalfSize * shapeHalfSize);", fEllipseName.vsOut()); 808a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 809a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBloatedRadius.vsOut()) { 810a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(fShapeIsCircle); 811a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = shapeHalfSize.x + 0.5;", fBloatedRadius.vsOut()); 812a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 813a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.vsOut()) { 814a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = int(%s != 0);", 815a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs)); 816a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 817a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fColorTimesRectCoverage.vsOut() || fRectCoverage.vsOut()) { 818a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("rectCoverage = 1.0;"); 819a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 820a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 821a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 822a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::adjustRRectVertices(GrGLSLVertexBuilder* v) { 823a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // We try to let the AA borders line up with the arc edges on their particular side, but we 824a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // can't allow them to get closer than one half pixel to the edge or they might overlap with 825a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // their neighboring border. 826a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("vec2 innerEdge = max(1.0 - bloat, vec2(0));"); 827a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 borderEdge = cornerSign * clamp(1.0 - radii, -innerEdge, innerEdge);"); 828a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // 0.5 is a special value that indicates this vertex is an arc edge. 829a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.x) == 0.5)" 830a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "bloatedShapeCoords.x = borderEdge.x;", fInputs.attr(Attrib::kShapeCoords)); 831a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.y) == 0.5)" 832a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "bloatedShapeCoords.y = borderEdge.y;", fInputs.attr(Attrib::kShapeCoords)); 833a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 834a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Adjust the interior border vertices to make the border one pixel wide. 0.75 is a special 835a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // value to indicate these points. 836a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.x) == 0.75) " 837a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "bloatedShapeCoords.x = cornerSign.x * innerEdge.x;", 838a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords)); 839a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.y) == 0.75) " 840a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "bloatedShapeCoords.y = cornerSign.y * innerEdge.y;", 841a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords)); 842a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 843a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 844a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onSetupRRect(GrGLSLVertexBuilder* v) { 845a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The geometry is laid out in such a way that rectCoverage will be 0 and 1 on the vertices, but 846a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // we still need to recompute this value because when the rrect gets thinner than one pixel, the 847a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // interior edge of the border will necessarily clamp, and we need to match the AA behavior of 848a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // the arc segments (i.e. distance from bloated edge only; ignoring the fact that the pixel 849a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // actully has less coverage because it's not completely inside the opposite edge.) 850a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("vec2 d = shapeHalfSize + 0.5 - abs(bloatedShapeCoords) * shapeHalfSize;"); 851a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("rectCoverage = min(d.x, d.y);"); 852a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 853a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!fShapeIsCircle); 854a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The AA border does not get closer than one half pixel to the edge of the rect, so to get a 855a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // smooth transition from flat edge to arc, we don't allow the radii to be smaller than one half 856a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // pixel. (We don't worry about the transition on the opposite side when a radius is so large 857a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // that the border clamped on that side.) 858a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 clampedRadii = max(radii, bloat);"); 859a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = (cornerSign * bloatedShapeCoords + clampedRadii - vec2(1)) * " 860a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "shapeHalfSize;", fEllipseCoords.vsOut()); 861a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 1.0 / (clampedRadii * clampedRadii * shapeHalfSize * shapeHalfSize);", 862a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fEllipseName.vsOut()); 863a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 864a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 865a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler, 866a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v) { 867a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("vec2 innerShapeHalfSize = shapeHalfSize / outer2Inner.xy;"); 868a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 869a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kOval_ShapeFlag == fBatchInfo.fInnerShapeTypes) { 870a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("innerEllipseCoords", &fInnerEllipseCoords, 871a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kMedium_GrSLPrecision); 872dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addFlatVarying("innerEllipseName", &fInnerEllipseName, kHigh_GrSLPrecision); 873a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 874a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("distanceToInnerEdge", &fDistanceToInnerEdge, 875a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kMedium_GrSLPrecision); 876a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("innerShapeBloatedHalfSize", &fInnerShapeBloatedHalfSize, 877a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kMedium_GrSLPrecision); 878a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kRect_ShapeFlag != fBatchInfo.fInnerShapeTypes) { 879dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords, 880dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton kMedium_GrSLPrecision); 881a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("innerEllipseName", &fInnerEllipseName, 882dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton kHigh_GrSLPrecision); 883dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kMedium_GrSLPrecision); 884a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 885a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 886a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 887a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 888a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupInnerRect(GrGLSLVertexBuilder* v) { 889a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerRRect.vsOut()) { 890a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The fragment shader will generalize every inner shape as a round rect. Since this one 891a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // is a rect, we simply emit bogus parameters for the round rect (effectively negative 892a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // radii) that ensure the fragment shader always takes the "emitRect" codepath. 893a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s.xy = abs(outer2Inner.xy) * (1.0 + bloat) + abs(outer2Inner.zw);", 894a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerRRect.vsOut()); 895a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 896a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 897a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 898a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupInnerOval(GrGLSLVertexBuilder* v) { 899a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 1.0 / (innerShapeHalfSize * innerShapeHalfSize);", 900a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerEllipseName.vsOut()); 901a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerEllipseCoords.vsOut()) { 902a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = innerShapeCoords * innerShapeHalfSize;", fInnerEllipseCoords.vsOut()); 903a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 904a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerRRect.vsOut()) { 905a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(0, 0, innerShapeHalfSize);", fInnerRRect.vsOut()); 906a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 907a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 908a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 9090caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) { 910a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The distance to ellipse formula doesn't work well when the radii are less than half a pixel. 911a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("innerRadii = max(innerRadii, bloat);"); 912a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 1.0 / (innerRadii * innerRadii * innerShapeHalfSize * " 913a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "innerShapeHalfSize);", 914a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerEllipseName.vsOut()); 915a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(1.0 - innerRadii, innerShapeHalfSize);", fInnerRRect.vsOut()); 916a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 917a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 918a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onEmitCode(GrGLSLVertexBuilder* v, 919a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLPPFragmentBuilder* f, 920a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage, 921a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outColor) { 922a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fColorTimesRectCoverage.vsOut()) { 923a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!fRectCoverage.vsOut()); 924a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s * rectCoverage;", 925a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fColorTimesRectCoverage.vsOut(), fInputs.attr(Attrib::kColor)); 926a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 927a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fRectCoverage.vsOut()) { 928a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!fColorTimesRectCoverage.vsOut()); 929a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = rectCoverage;", fRectCoverage.vsOut()); 930a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 931a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 932a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkString coverage("float coverage"); 933a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (f->getProgramBuilder()->glslCaps()->usesPrecisionModifiers()) { 934a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton coverage.prependf("lowp "); 935a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 936a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBatchInfo.fInnerShapeTypes || (!fTweakAlphaForCoverage && fTriangleIsArc.fsIn())) { 937a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s;", coverage.c_str()); 938a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton coverage = "coverage"; 939a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 940a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.fsIn()) { 941a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s == 0) {", fTriangleIsArc.fsIn()); 942a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, coverage.c_str(), outColor); 943a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 944a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fShapeIsCircle) { 945a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitCircle(f, coverage.c_str()); 946a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 947a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool ellipseCoordsMayBeNegative = SkToBool(fBatchInfo.fShapeTypes & kOval_ShapeFlag); 948a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, fEllipseCoords.fsIn(), fEllipseName.fsIn(), 949a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton true /*ellipseCoordsNeedClamp*/, ellipseCoordsMayBeNegative, 950a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton coverage.c_str()); 951a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 952a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTweakAlphaForCoverage) { 953a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = %s * coverage;", outColor, fColor.fsIn()); 954a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 955a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 956a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 957a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, coverage.c_str(), outColor); 958a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 959a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 960a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBatchInfo.fInnerShapeTypes) { 961a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("// Inner shape.\n"); 962a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkString innerCoverageDecl("float innerCoverage"); 963a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (f->getProgramBuilder()->glslCaps()->usesPrecisionModifiers()) { 964a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerCoverageDecl.prependf("lowp "); 965a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 966a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kOval_ShapeFlag == fBatchInfo.fInnerShapeTypes) { 967a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, fInnerEllipseCoords.fsIn(), fInnerEllipseName.fsIn(), 968a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton true /*ellipseCoordsNeedClamp*/, true /*ellipseCoordsMayBeNegative*/, 969a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerCoverageDecl.c_str()); 970a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 971a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = innerShapeCoords * innerShapeHalfSize;", 972a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fDistanceToInnerEdge.vsOut()); 973a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = innerShapeHalfSize + 0.5;", fInnerShapeBloatedHalfSize.vsOut()); 974a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 975a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kRect_ShapeFlag == fBatchInfo.fInnerShapeTypes) { 976a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitInnerRect(f, innerCoverageDecl.c_str()); 977a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 978a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = 0.0;", innerCoverageDecl.c_str()); 979dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton f->appendPrecisionModifier(kMedium_GrSLPrecision); 980a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("vec2 distanceToArcEdge = abs(%s) - %s.xy;", 981a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeCoords.fsIn(), fInnerRRect.fsIn()); 982a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("if (any(lessThan(distanceToArcEdge, vec2(1e-5)))) {"); 983a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitInnerRect(f, "innerCoverage"); 984a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 985dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton f->appendPrecisionModifier(kMedium_GrSLPrecision); 986a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "vec2 ellipseCoords = distanceToArcEdge * %s.zw;", 987a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerRRect.fsIn()); 988a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, "ellipseCoords", fInnerEllipseName.fsIn(), 989a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton false /*ellipseCoordsNeedClamp*/, 990a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton false /*ellipseCoordsMayBeNegative*/, "innerCoverage"); 991a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 992a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 993a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 994a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = vec4(max(coverage - innerCoverage, 0.0));", outCoverage); 995a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (!fTweakAlphaForCoverage) { 996a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = vec4(coverage);", outCoverage); 997a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 998a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 999a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1000a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitRect(GrGLSLPPFragmentBuilder* f, 1001a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage, 1002a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outColor) { 1003a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fColorTimesRectCoverage.fsIn()) { 1004a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = %s;", outColor, fColorTimesRectCoverage.fsIn()); 1005a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fTweakAlphaForCoverage) { 1006a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // We are drawing just ovals. The interior rect always has 100% coverage. 1007a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = %s;", outColor, fColor.fsIn()); 1008a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fRectCoverage.fsIn()) { 1009a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = %s;", outCoverage, fRectCoverage.fsIn()); 1010a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1011a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = 1.0;", outCoverage); 1012a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1013a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1014a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1015a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitCircle(GrGLSLPPFragmentBuilder* f, 1016a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage) { 1017a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // TODO: circleCoords = max(circleCoords, 0) if we decide to do this optimization on rrects. 1018a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!(kRRect_ShapesMask & fBatchInfo.fShapeTypes)); 1019dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton f->appendPrecisionModifier(kLow_GrSLPrecision); 1020a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("float distanceToEdge = %s - length(%s);", 1021a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fBloatedRadius.fsIn(), fEllipseCoords.fsIn()); 1022a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = clamp(distanceToEdge, 0.0, 1.0);", outCoverage); 1023a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1024a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1025a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitArc(GrGLSLPPFragmentBuilder* f, 1026a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* ellipseCoords, 1027a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* ellipseName, 1028a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool ellipseCoordsNeedClamp, 1029a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool ellipseCoordsMayBeNegative, 1030a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage) { 1031a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!ellipseCoordsMayBeNegative || ellipseCoordsNeedClamp); 1032a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (ellipseCoordsNeedClamp) { 1033a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // This serves two purposes: 1034a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // - To restrict the arcs of rounded rects to their positive quadrants. 1035a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // - To avoid inversesqrt(0) in the ellipse formula. 1036dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton f->appendPrecisionModifier(kMedium_GrSLPrecision); 1037a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (ellipseCoordsMayBeNegative) { 1038a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("vec2 ellipseClampedCoords = max(abs(%s), vec2(1e-4));", ellipseCoords); 1039a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1040a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("vec2 ellipseClampedCoords = max(%s, vec2(1e-4));", ellipseCoords); 1041a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1042a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton ellipseCoords = "ellipseClampedCoords"; 1043a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1044a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // ellipseCoords are in pixel space and ellipseName is 1 / rx^2, 1 / ry^2. 1045dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1046a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("vec2 Z = %s * %s;", ellipseCoords, ellipseName); 1047a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1. 1048dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1049a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("float implicit = dot(Z, %s) - 1.0;", ellipseCoords); 1050a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // gradDot is the squared length of the gradient of the implicit. 1051dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1052a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("float gradDot = 4.0 * dot(Z, Z);"); 1053dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton f->appendPrecisionModifier(kMedium_GrSLPrecision); 1054a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("float approxDist = implicit * inversesqrt(gradDot);"); 1055a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = clamp(0.5 - approxDist, 0.0, 1.0);", outCoverage); 1056a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1057a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1058a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitInnerRect(GrGLSLPPFragmentBuilder* f, 1059a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage) { 1060a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kLow_GrSLPrecision); 1061a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("vec2 c = %s - abs(%s);", 1062a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeBloatedHalfSize.fsIn(), fDistanceToInnerEdge.fsIn()); 1063a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = clamp(min(c.x, c.y), 0.0, 1.0);", outCoverage); 1064a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1065a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1066a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton//////////////////////////////////////////////////////////////////////////////////////////////////// 1067a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1068a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::BackendMultisample : public Backend { 1069a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic: 1070a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton BackendMultisample(BatchInfo batchInfo, const VertexInputs& inputs, int effectiveSampleCnt) 1071a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton : INHERITED(batchInfo, inputs), 1072a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fEffectiveSampleCnt(effectiveSampleCnt), 1073a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fShapeCoords(kVec2f_GrSLType), 1074a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fShapeInverseMatrix(kMat22f_GrSLType), 1075a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fFragShapeHalfSpan(kVec2f_GrSLType), 1076a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcTest(kVec2f_GrSLType), 1077a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcInverseMatrix(kMat22f_GrSLType), 1078a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fFragArcHalfSpan(kVec2f_GrSLType), 1079a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fEarlyAccept(kInt_GrSLType), 1080a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeInverseMatrix(kMat22f_GrSLType), 1081a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fFragInnerShapeHalfSpan(kVec2f_GrSLType) { 1082a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fRectTrianglesMaySplit = fBatchInfo.fHasPerspective; 1083a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fNeedsNeighborRadii = this->isMixedSampled() && !fBatchInfo.fHasPerspective; 1084a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1085a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1086a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate: 1087a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool isMixedSampled() const { return AntialiasMode::kMixedSamples == fBatchInfo.fAntialiasMode; } 1088a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1089a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override; 1090a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupRect(GrGLSLVertexBuilder*) override; 1091a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupOval(GrGLSLVertexBuilder*) override; 1092a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void adjustRRectVertices(GrGLSLVertexBuilder*) override; 1093a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onSetupRRect(GrGLSLVertexBuilder*) override; 1094a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1095a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override; 1096a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupInnerRect(GrGLSLVertexBuilder*) override; 1097a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupInnerOval(GrGLSLVertexBuilder*) override; 10980caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override; 1099a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1100a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char*, 1101a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char*) override; 1102a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1103a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton struct EmitShapeCoords { 1104a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const GrGLSLVarying* fVarying; 1105a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* fInverseMatrix; 1106a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* fFragHalfSpan; 1107a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton }; 1108a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1109a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton struct EmitShapeOpts { 1110a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fIsTightGeometry; 1111a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fResolveMixedSamples; 1112a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fInvertCoverage; 1113a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton }; 1114a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1115a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitRect(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, const EmitShapeOpts&); 1116a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitArc(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, bool coordsMayBeNegative, 1117a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool clampCoords, const EmitShapeOpts&); 1118a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitSimpleRRect(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, const char* rrect, 1119a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeOpts&); 1120a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void interpolateAtSample(GrGLSLPPFragmentBuilder*, const GrGLSLVarying&, const char* sampleIdx, 1121a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* interpolationMatrix); 1122a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void acceptOrRejectWholeFragment(GrGLSLPPFragmentBuilder*, bool inside, const EmitShapeOpts&); 1123a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void acceptCoverageMask(GrGLSLPPFragmentBuilder*, const char* shapeMask, const EmitShapeOpts&, 1124a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool maybeSharedEdge = true); 1125a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1126a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton int fEffectiveSampleCnt; 1127a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fRectTrianglesMaySplit; 1128a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fShapeCoords; 1129a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fShapeInverseMatrix; 1130a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fFragShapeHalfSpan; 1131a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fArcTest; 1132a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fArcInverseMatrix; 1133a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fFragArcHalfSpan; 1134a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fEarlyAccept; 1135a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fInnerShapeInverseMatrix; 1136a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fFragInnerShapeHalfSpan; 1137a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkString fSquareFun; 1138a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1139a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton typedef Backend INHERITED; 1140a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 1141a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1142a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onInit(GrGLSLVaryingHandler* varyingHandler, 1143a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v) { 1144a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!this->isMixedSampled()) { 1145a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) { 1146dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision); 1147a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("arcCoords", &fArcCoords, kHigh_GrSLPrecision); 1148a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fBatchInfo.fHasPerspective) { 1149a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("arcInverseMatrix", &fArcInverseMatrix, 1150a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1151a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("fragArcHalfSpan", &fFragArcHalfSpan, 1152a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1153a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1154a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (!fBatchInfo.fInnerShapeTypes) { 1155a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return; 1156a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1157a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1158a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("shapeCoords", &fShapeCoords, kHigh_GrSLPrecision); 1159a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fBatchInfo.fHasPerspective) { 1160a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("shapeInverseMatrix", &fShapeInverseMatrix, 1161a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1162a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("fragShapeHalfSpan", &fFragShapeHalfSpan, 1163a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1164a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1165a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBatchInfo.fShapeTypes & kRRect_ShapesMask) { 1166a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("arcCoords", &fArcCoords, kHigh_GrSLPrecision); 1167a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("arcTest", &fArcTest, kHigh_GrSLPrecision); 1168a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fBatchInfo.fHasPerspective) { 1169a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("arcInverseMatrix", &fArcInverseMatrix, 1170a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1171a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("fragArcHalfSpan", &fFragArcHalfSpan, 1172a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1173a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1174a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fBatchInfo.fShapeTypes & kOval_ShapeFlag) { 1175a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcCoords = fShapeCoords; 1176a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcInverseMatrix = fShapeInverseMatrix; 1177a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fFragArcHalfSpan = fFragShapeHalfSpan; 1178a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBatchInfo.fShapeTypes & kRect_ShapeFlag) { 1179a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, 1180dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton kLow_GrSLPrecision); 1181a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1182a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1183a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) { 1184a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->definef("SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1); 1185a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("earlyAccept", &fEarlyAccept, kHigh_GrSLPrecision); 1186a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1187a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1188a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fBatchInfo.fHasPerspective) { 1189a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("mat2 shapeInverseMatrix = inverse(mat2(shapeMatrix));"); 1190a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("vec2 fragShapeSpan = abs(vec4(shapeInverseMatrix).xz) + " 1191a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "abs(vec4(shapeInverseMatrix).yw);"); 1192a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1193a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1194a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1195a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupRect(GrGLSLVertexBuilder* v) { 1196a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fShapeCoords.vsOut()) { 1197a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s;", fShapeCoords.vsOut(), this->outShapeCoords()); 1198a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1199a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fShapeInverseMatrix.vsOut()) { 1200a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = shapeInverseMatrix;", fShapeInverseMatrix.vsOut()); 1201a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1202a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fFragShapeHalfSpan.vsOut()) { 1203a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragShapeHalfSpan.vsOut()); 1204a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1205a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fArcTest.vsOut()) { 1206a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Pick a value that is not > 0. 1207a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec2(0);", fArcTest.vsOut()); 1208a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1209a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.vsOut()) { 1210a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut()); 1211a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1212a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fEarlyAccept.vsOut()) { 1213a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = SAMPLE_MASK_ALL;", fEarlyAccept.vsOut()); 1214a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1215a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1216a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1217a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupOval(GrGLSLVertexBuilder* v) { 1218a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = abs(%s);", fArcCoords.vsOut(), this->outShapeCoords()); 1219a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fArcInverseMatrix.vsOut()) { 1220a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 s = sign(%s);", this->outShapeCoords()); 1221a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = shapeInverseMatrix * mat2(s.x, 0, 0 , s.y);", 1222a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcInverseMatrix.vsOut()); 1223a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1224a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fFragArcHalfSpan.vsOut()) { 1225a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragArcHalfSpan.vsOut()); 1226a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1227a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fArcTest.vsOut()) { 1228a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Pick a value that is > 0. 1229a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec2(1);", fArcTest.vsOut()); 1230a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1231a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.vsOut()) { 1232a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!this->isMixedSampled()) { 1233a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s & 1;", 1234a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs)); 1235a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1236a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 1;", fTriangleIsArc.vsOut()); 1237a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1238a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1239a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fEarlyAccept.vsOut()) { 1240a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = ~%s & SAMPLE_MASK_ALL;", 1241a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fEarlyAccept.vsOut(), fInputs.attr(Attrib::kVertexAttrs)); 1242a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1243a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1244a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1245a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::adjustRRectVertices(GrGLSLVertexBuilder* v) { 1246a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!this->isMixedSampled()) { 1247a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton INHERITED::adjustRRectVertices(v); 1248a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return; 1249a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1250a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1251a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fBatchInfo.fHasPerspective) { 1252a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // For the mixed samples algorithm it's best to bloat the corner triangles a bit so that 1253a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // more of the pixels that cross into the arc region are completely inside the shared edges. 1254a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // We also snap to a regular rect if the radii shrink smaller than a pixel. 1255a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 midpt = 0.5 * (neighborRadii - radii);"); 1256a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 cornerSize = any(lessThan(radii, fragShapeSpan)) ? " 1257a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "vec2(0) : min(radii + 0.5 * fragShapeSpan, 1.0 - midpt);"); 1258a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1259a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // TODO: We could still bloat the corner triangle in the perspective case; we would just 1260a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // need to find the screen-space derivative of shape coords at this particular point. 1261a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 cornerSize = any(lessThan(radii, vec2(1e-3))) ? vec2(0) : radii;"); 1262a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1263a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1264a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.x) == 0.5)" 1265a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "%s.x = cornerSign.x * (1.0 - cornerSize.x);", 1266a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords); 1267a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.y) == 0.5)" 1268a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "%s.y = cornerSign.y * (1.0 - cornerSize.y);", 1269a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords); 1270a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1271a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1272a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onSetupRRect(GrGLSLVertexBuilder* v) { 1273a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fShapeCoords.vsOut()) { 1274a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s;", fShapeCoords.vsOut(), this->outShapeCoords()); 1275a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1276a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fShapeInverseMatrix.vsOut()) { 1277a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = shapeInverseMatrix;", fShapeInverseMatrix.vsOut()); 1278a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1279a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fFragShapeHalfSpan.vsOut()) { 1280a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragShapeHalfSpan.vsOut()); 1281a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1282a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fArcInverseMatrix.vsOut()) { 1283a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 s = cornerSign / radii;"); 1284a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = shapeInverseMatrix * mat2(s.x, 0, 0, s.y);", 1285a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcInverseMatrix.vsOut()); 1286a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1287a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fFragArcHalfSpan.vsOut()) { 1288a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0.5 * (abs(vec4(%s).xz) + abs(vec4(%s).yw));", 1289a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fFragArcHalfSpan.vsOut(), fArcInverseMatrix.vsOut(), 1290a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcInverseMatrix.vsOut()); 1291a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1292a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fArcTest.vsOut()) { 1293a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The interior triangles are laid out as a fan. fArcTest is both distances from shared 1294a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // edges of a fan triangle to a point within that triangle. fArcTest is used to check if a 1295a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // fragment is too close to either shared edge, in which case we point sample the shape as a 1296a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // rect at that point in order to guarantee the mixed samples discard logic works correctly. 1297a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = (cornerSize == vec2(0)) ? vec2(0) : " 1298a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "cornerSign * %s * mat2(1, cornerSize.x - 1.0, cornerSize.y - 1.0, 1);", 1299a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcTest.vsOut(), fModifiedShapeCoords); 1300a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fBatchInfo.fHasPerspective) { 1301a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Shift the point at which distances to edges are measured from the center of the pixel 1302a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // to the corner. This way the sign of fArcTest will quickly tell us whether a pixel 1303a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // is completely inside the shared edge. Perspective mode will accomplish this same task 1304a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // by finding the derivatives in the fragment shader. 1305a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s -= 0.5 * (fragShapeSpan.yx * abs(radii - 1.0) + fragShapeSpan);", 1306a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcTest.vsOut()); 1307a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1308a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1309a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fEarlyAccept.vsOut()) { 1310a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(this->isMixedSampled()); 1311a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = all(equal(vec2(1), abs(%s))) ? 0 : SAMPLE_MASK_ALL;", 1312a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fEarlyAccept.vsOut(), fInputs.attr(Attrib::kShapeCoords)); 1313a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1314a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1315a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1316a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid 1317a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGLSLInstanceProcessor::BackendMultisample::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler, 1318a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v) { 1319a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords, kHigh_GrSLPrecision); 1320a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kOval_ShapeFlag != fBatchInfo.fInnerShapeTypes && 1321a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kRect_ShapeFlag != fBatchInfo.fInnerShapeTypes) { 1322a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kHigh_GrSLPrecision); 1323a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1324a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fBatchInfo.fHasPerspective) { 1325a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("innerShapeInverseMatrix", &fInnerShapeInverseMatrix, 1326a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1327a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = shapeInverseMatrix * mat2(outer2Inner.x, 0, 0, outer2Inner.y);", 1328a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeInverseMatrix.vsOut()); 1329a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("fragInnerShapeHalfSpan", &fFragInnerShapeHalfSpan, 1330a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1331a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0.5 * fragShapeSpan * outer2Inner.xy;", 1332a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fFragInnerShapeHalfSpan.vsOut()); 1333a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1334a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1335a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1336a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupInnerRect(GrGLSLVertexBuilder* v) { 1337a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerRRect.vsOut()) { 1338a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The fragment shader will generalize every inner shape as a round rect. Since this one 1339a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // is a rect, we simply emit bogus parameters for the round rect (negative radii) that 1340a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // ensure the fragment shader always takes the "sample as rect" codepath. 1341a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(2.0 * (inner.zw - inner.xy) / (outer.zw - outer.xy), vec2(0));", 1342a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerRRect.vsOut()); 1343a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1344a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1345a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1346a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupInnerOval(GrGLSLVertexBuilder* v) { 1347a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerRRect.vsOut()) { 1348a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(0, 0, 1, 1);", fInnerRRect.vsOut()); 1349a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1350a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1351a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 13520caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) { 1353a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Avoid numeric instability by not allowing the inner radii to get smaller than 1/10th pixel. 1354a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fFragInnerShapeHalfSpan.vsOut()) { 1355a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("innerRadii = max(innerRadii, 2e-1 * %s);", fFragInnerShapeHalfSpan.vsOut()); 1356a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1357a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("innerRadii = max(innerRadii, vec2(1e-4));"); 1358a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1359a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(1.0 - innerRadii, 1.0 / innerRadii);", fInnerRRect.vsOut()); 1360a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1361a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1362a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onEmitCode(GrGLSLVertexBuilder*, 1363a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLPPFragmentBuilder* f, 1364a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char*, const char*) { 1365a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->define("SAMPLE_COUNT", fEffectiveSampleCnt); 1366a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (this->isMixedSampled()) { 1367a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->definef("SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1); 1368a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->definef("SAMPLE_MASK_MSB", "0x%x", 1 << (fEffectiveSampleCnt - 1)); 1369a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1370a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1371a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kRect_ShapeFlag != (fBatchInfo.fShapeTypes | fBatchInfo.fInnerShapeTypes)) { 1372a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLShaderVar x("x", kVec2f_GrSLType, GrGLSLShaderVar::kNonArray, kHigh_GrSLPrecision); 1373a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->emitFunction(kFloat_GrSLType, "square", 1, &x, "return dot(x, x);", &fSquareFun); 1374a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1375a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1376a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton EmitShapeCoords shapeCoords; 1377a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton shapeCoords.fVarying = &fShapeCoords; 1378a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton shapeCoords.fInverseMatrix = fShapeInverseMatrix.fsIn(); 1379a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton shapeCoords.fFragHalfSpan = fFragShapeHalfSpan.fsIn(); 1380a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1381a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton EmitShapeCoords arcCoords; 1382a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton arcCoords.fVarying = &fArcCoords; 1383a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton arcCoords.fInverseMatrix = fArcInverseMatrix.fsIn(); 1384a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton arcCoords.fFragHalfSpan = fFragArcHalfSpan.fsIn(); 1385a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool clampArcCoords = this->isMixedSampled() && (fBatchInfo.fShapeTypes & kRRect_ShapesMask); 1386a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1387a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton EmitShapeOpts opts; 1388a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton opts.fIsTightGeometry = true; 1389a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton opts.fResolveMixedSamples = this->isMixedSampled(); 1390a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton opts.fInvertCoverage = false; 1391a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1392a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBatchInfo.fHasPerspective && fBatchInfo.fInnerShapeTypes) { 1393a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // This determines if the fragment should consider the inner shape in its sample mask. 1394a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // We take the derivative early in case discards may occur before we get to the inner shape. 1395a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1396a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("vec2 fragInnerShapeApproxHalfSpan = 0.5 * fwidth(%s);", 1397a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeCoords.fsIn()); 1398a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1399a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1400a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!this->isMixedSampled()) { 1401a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!fArcTest.fsIn()); 1402a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.fsIn()) { 1403a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s != 0) {", fTriangleIsArc.fsIn()); 1404a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, arcCoords, false, clampArcCoords, opts); 1405a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1406a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1407a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1408a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1409a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* arcTest = fArcTest.fsIn(); 1410a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(arcTest); 1411a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBatchInfo.fHasPerspective) { 1412a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The non-perspective version accounts for fwith() in the vertex shader. 1413a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // We make sure to take the derivative here, before a neighbor pixel may early accept. 1414a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->enableFeature(GrGLSLPPFragmentBuilder::kStandardDerivatives_GLSLFeature); 1415a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1416a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("vec2 arcTest = %s - 0.5 * fwidth(%s);", 1417a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcTest.fsIn(), fArcTest.fsIn()); 1418a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton arcTest = "arcTest"; 1419a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1420a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* earlyAccept = fEarlyAccept.fsIn() ? fEarlyAccept.fsIn() : "SAMPLE_MASK_ALL"; 1421a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (gl_SampleMaskIn[0] == %s) {", earlyAccept); 1422a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage(earlyAccept); 1423a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 1424a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (arcTest) { 1425a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // At this point, if the sample mask is all set it means we are inside an arc triangle. 1426a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (gl_SampleMaskIn[0] == SAMPLE_MASK_ALL || " 1427a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "all(greaterThan(%s, vec2(0)))) {", arcTest); 1428a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, arcCoords, false, clampArcCoords, opts); 1429a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 1430a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, shapeCoords, opts); 1431a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1432a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fTriangleIsArc.fsIn()) { 1433a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s == 0) {", fTriangleIsArc.fsIn()); 1434a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, shapeCoords, opts); 1435a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 1436a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, arcCoords, false, clampArcCoords, opts); 1437a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1438a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fBatchInfo.fShapeTypes == kOval_ShapeFlag) { 1439a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, arcCoords, false, clampArcCoords, opts); 1440a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1441a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(fBatchInfo.fShapeTypes == kRect_ShapeFlag); 1442a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, shapeCoords, opts); 1443a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1444a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1445a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1446a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1447a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBatchInfo.fInnerShapeTypes) { 1448a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("// Inner shape.\n"); 1449a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1450a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton EmitShapeCoords innerShapeCoords; 1451a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerShapeCoords.fVarying = &fInnerShapeCoords; 1452a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fBatchInfo.fHasPerspective) { 1453a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerShapeCoords.fInverseMatrix = fInnerShapeInverseMatrix.fsIn(); 1454a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerShapeCoords.fFragHalfSpan = fFragInnerShapeHalfSpan.fsIn(); 1455a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1456a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1457a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton EmitShapeOpts innerOpts; 1458a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerOpts.fIsTightGeometry = false; 1459a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerOpts.fResolveMixedSamples = false; // Mixed samples are resolved in the outer shape. 1460a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerOpts.fInvertCoverage = true; 1461a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1462a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kOval_ShapeFlag == fBatchInfo.fInnerShapeTypes) { 1463a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, innerShapeCoords, true, false, innerOpts); 1464a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1465a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (all(lessThan(abs(%s), 1.0 + %s))) {", fInnerShapeCoords.fsIn(), 1466a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton !fBatchInfo.fHasPerspective ? innerShapeCoords.fFragHalfSpan 1467a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton : "fragInnerShapeApproxHalfSpan"); // Above. 1468a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kRect_ShapeFlag == fBatchInfo.fInnerShapeTypes) { 1469a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, innerShapeCoords, innerOpts); 1470a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1471a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitSimpleRRect(f, innerShapeCoords, fInnerRRect.fsIn(), innerOpts); 1472a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1473a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1474a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1475a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1476a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1477a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1478a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::emitRect(GrGLSLPPFragmentBuilder* f, 1479a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeCoords& coords, 1480a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeOpts& opts) { 1481a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Full MSAA doesn't need to do anything to draw a rect. 1482a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!opts.fIsTightGeometry || opts.fResolveMixedSamples); 1483a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (coords.fFragHalfSpan) { 1484a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (all(lessThanEqual(abs(%s), 1.0 - %s))) {", 1485a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton coords.fVarying->fsIn(), coords.fFragHalfSpan); 1486a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The entire pixel is inside the rect. 1487a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptOrRejectWholeFragment(f, true, opts); 1488a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else "); 1489a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (opts.fIsTightGeometry && !fRectTrianglesMaySplit) { 1490a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (any(lessThan(abs(%s), 1.0 - %s))) {", 1491a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton coords.fVarying->fsIn(), coords.fFragHalfSpan); 1492a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The pixel falls on an edge of the rectangle and is known to not be on a shared edge. 1493a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptCoverageMask(f, "gl_SampleMaskIn[0]", opts, false); 1494a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else"); 1495a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1496a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("{"); 1497a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1498a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("int rectMask = 0;"); 1499a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("for (int i = 0; i < SAMPLE_COUNT; i++) {"); 1500a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1501a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "vec2 pt = "); 1502a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->interpolateAtSample(f, *coords.fVarying, "i", coords.fInverseMatrix); 1503a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( ";"); 1504a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "if (all(lessThan(abs(pt), vec2(1)))) rectMask |= (1 << i);"); 1505a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1506a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptCoverageMask(f, "rectMask", opts); 1507a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (coords.fFragHalfSpan) { 1508a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1509a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1510a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1511a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1512a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::emitArc(GrGLSLPPFragmentBuilder* f, 1513a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeCoords& coords, 1514a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool coordsMayBeNegative, bool clampCoords, 1515a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeOpts& opts) { 1516a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (coords.fFragHalfSpan) { 1517a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkString absArcCoords; 1518a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton absArcCoords.printf(coordsMayBeNegative ? "abs(%s)" : "%s", coords.fVarying->fsIn()); 1519a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (clampCoords) { 1520a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s(max(%s + %s, vec2(0))) < 1.0) {", 1521a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan); 1522a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1523a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s(%s + %s) < 1.0) {", 1524a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan); 1525a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1526a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The entire pixel is inside the arc. 1527a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptOrRejectWholeFragment(f, true, opts); 1528a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("} else if (%s(max(%s - %s, vec2(0))) >= 1.0) {", 1529a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan); 1530a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The entire pixel is outside the arc. 1531a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptOrRejectWholeFragment(f, false, opts); 1532a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 1533a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1534a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "int arcMask = 0;"); 1535a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "for (int i = 0; i < SAMPLE_COUNT; i++) {"); 1536a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1537a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "vec2 pt = "); 1538a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->interpolateAtSample(f, *coords.fVarying, "i", coords.fInverseMatrix); 1539a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( ";"); 1540a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (clampCoords) { 1541a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!coordsMayBeNegative); 1542a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "pt = max(pt, vec2(0));"); 1543a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1544a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "if (%s(pt) < 1.0) arcMask |= (1 << i);", fSquareFun.c_str()); 1545a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "}"); 1546a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptCoverageMask(f, "arcMask", opts); 1547a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (coords.fFragHalfSpan) { 1548a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1549a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1550a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1551a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1552a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::emitSimpleRRect(GrGLSLPPFragmentBuilder* f, 1553a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeCoords& coords, 1554a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* rrect, 1555a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeOpts& opts) { 1556a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1557a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("vec2 distanceToArcEdge = abs(%s) - %s.xy;", coords.fVarying->fsIn(), rrect); 1558a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("if (any(lessThan(distanceToArcEdge, vec2(0)))) {"); 1559a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, coords, opts); 1560a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 1561a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (coords.fInverseMatrix && coords.fFragHalfSpan) { 1562a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1563a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("vec2 rrectCoords = distanceToArcEdge * %s.zw;", rrect); 1564a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1565a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("vec2 fragRRectHalfSpan = %s * %s.zw;", coords.fFragHalfSpan, rrect); 1566a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s(rrectCoords + fragRRectHalfSpan) <= 1.0) {", fSquareFun.c_str()); 1567a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The entire pixel is inside the round rect. 1568a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptOrRejectWholeFragment(f, true, opts); 1569a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("} else if (%s(max(rrectCoords - fragRRectHalfSpan, vec2(0))) >= 1.0) {", 1570a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fSquareFun.c_str()); 1571a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The entire pixel is outside the round rect. 1572a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptOrRejectWholeFragment(f, false, opts); 1573a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 1574a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1575a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "vec2 s = %s.zw * sign(%s);", rrect, coords.fVarying->fsIn()); 1576a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1577a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "mat2 innerRRectInverseMatrix = %s * mat2(s.x, 0, 0, s.y);", 1578a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton coords.fInverseMatrix); 1579a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1580a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "int rrectMask = 0;"); 1581a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "for (int i = 0; i < SAMPLE_COUNT; i++) {"); 1582a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1583a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "vec2 pt = rrectCoords + "); 1584a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendOffsetToSample("i", GrGLSLFPFragmentBuilder::kSkiaDevice_Coordinates); 1585a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "* innerRRectInverseMatrix;"); 1586a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "if (%s(max(pt, vec2(0))) < 1.0) rrectMask |= (1 << i);", 1587a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fSquareFun.c_str()); 1588a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "}"); 1589a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptCoverageMask(f, "rrectMask", opts); 1590a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1591a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1592a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("int rrectMask = 0;"); 1593a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("for (int i = 0; i < SAMPLE_COUNT; i++) {"); 1594a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1595a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "vec2 shapePt = "); 1596a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->interpolateAtSample(f, *coords.fVarying, "i", nullptr); 1597a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( ";"); 1598a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendPrecisionModifier(kHigh_GrSLPrecision); 1599a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "vec2 rrectPt = max(abs(shapePt) - %s.xy, vec2(0)) * %s.zw;", 1600a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton rrect, rrect); 1601a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "if (%s(rrectPt) < 1.0) rrectMask |= (1 << i);", fSquareFun.c_str()); 1602a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1603a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptCoverageMask(f, "rrectMask", opts); 1604a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1605a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1606a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1607a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1608a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::interpolateAtSample(GrGLSLPPFragmentBuilder* f, 1609a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const GrGLSLVarying& varying, 1610a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* sampleIdx, 1611a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* interpolationMatrix) { 1612a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (interpolationMatrix) { 1613a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("(%s + ", varying.fsIn()); 1614a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendOffsetToSample(sampleIdx, GrGLSLFPFragmentBuilder::kSkiaDevice_Coordinates); 1615a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf(" * %s)", interpolationMatrix); 1616a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1617a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkAssertResult( 1618a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->enableFeature(GrGLSLFragmentBuilder::kMultisampleInterpolation_GLSLFeature)); 1619a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("interpolateAtOffset(%s, ", varying.fsIn()); 1620a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendOffsetToSample(sampleIdx, GrGLSLFPFragmentBuilder::kGLSLWindow_Coordinates); 1621a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend(")"); 1622a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1623a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1624a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1625a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid 1626a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGLSLInstanceProcessor::BackendMultisample::acceptOrRejectWholeFragment(GrGLSLPPFragmentBuilder* f, 1627a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool inside, 1628a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeOpts& opts) { 1629a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (inside != opts.fInvertCoverage) { // Accept the entire fragment. 1630a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (opts.fResolveMixedSamples) { 1631a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // This is a mixed sampled fragment in the interior of the shape. Reassign 100% coverage 1632a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // to one fragment, and drop all other fragments that may fall on this same pixel. Since 1633a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // our geometry is water tight and non-overlapping, we can take advantage of the 1634a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // properties that (1) the incoming sample masks will be disjoint across fragments that 1635a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // fall on a common pixel, and (2) since the entire fragment is inside the shape, each 1636a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // sample's corresponding bit will be set in the incoming sample mask of exactly one 1637a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // fragment. 1638a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend("if ((gl_SampleMaskIn[0] & SAMPLE_MASK_MSB) == 0) {"); 1639a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Drop this fragment. 1640a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fBatchInfo.fCannotDiscard) { 1641a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend("discard;"); 1642a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1643a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage("0"); 1644a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1645a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend("} else {"); 1646a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Override the lone surviving fragment to full coverage. 1647a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage("-1"); 1648a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend("}"); 1649a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1650a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { // Reject the entire fragment. 1651a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fBatchInfo.fCannotDiscard) { 1652a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend("discard;"); 1653a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (opts.fResolveMixedSamples) { 1654a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage("0"); 1655a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1656a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->maskSampleCoverage("0"); 1657a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1658a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1659a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1660a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1661a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::acceptCoverageMask(GrGLSLPPFragmentBuilder* f, 1662a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* shapeMask, 1663a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeOpts& opts, 1664a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool maybeSharedEdge) { 1665a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (opts.fResolveMixedSamples) { 1666a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (maybeSharedEdge) { 1667a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // This is a mixed sampled fragment, potentially on the outer edge of the shape, with 1668a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // only partial shape coverage. Override the coverage of one fragment to "shapeMask", 1669a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // and drop all other fragments that may fall on this same pixel. Since our geometry is 1670a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // water tight, non-overlapping, and completely contains the shape, this means that each 1671a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // "on" bit from shapeMask is guaranteed to be set in the incoming sample mask of one, 1672a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // and only one, fragment that falls on this same pixel. 1673a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!opts.fInvertCoverage); 1674a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if ((gl_SampleMaskIn[0] & (1 << findMSB(%s))) == 0) {", shapeMask); 1675a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Drop this fragment. 1676a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fBatchInfo.fCannotDiscard) { 1677a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("discard;"); 1678a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1679a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage("0"); 1680a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1681a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 1682a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Override the coverage of the lone surviving fragment to "shapeMask". 1683a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage(shapeMask); 1684a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1685a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1686a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage(shapeMask); 1687a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1688a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1689a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->maskSampleCoverage(shapeMask, opts.fInvertCoverage); 1690a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1691a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1692a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1693a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton//////////////////////////////////////////////////////////////////////////////////////////////////// 1694a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1695a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGLSLInstanceProcessor::Backend* 1696a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGLSLInstanceProcessor::Backend::Create(const GrPipeline& pipeline, BatchInfo batchInfo, 1697a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const VertexInputs& inputs) { 1698a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton switch (batchInfo.fAntialiasMode) { 1699a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton default: 1700a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkFAIL("Unexpected antialias mode."); 1701a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case AntialiasMode::kNone: 1702a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return new BackendNonAA(batchInfo, inputs); 1703a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case AntialiasMode::kCoverage: 1704a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return new BackendCoverage(batchInfo, inputs); 1705a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case AntialiasMode::kMSAA: 1706a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case AntialiasMode::kMixedSamples: { 1707a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const GrRenderTargetPriv& rtp = pipeline.getRenderTarget()->renderTargetPriv(); 1708a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const GrGpu::MultisampleSpecs& specs = rtp.getMultisampleSpecs(pipeline.getStencil()); 1709a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return new BackendMultisample(batchInfo, inputs, specs.fEffectiveSampleCnt); 1710a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1711a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1712a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1713a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1714a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton//////////////////////////////////////////////////////////////////////////////////////////////////// 1715a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1716a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst ShapeVertex kVertexData[] = { 1717a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Rectangle. 1718a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1, +1, ~0}, /*0*/ 1719a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1, +1, ~0}, /*1*/ 1720a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1, -1, ~0}, /*2*/ 1721a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1, -1, ~0}, /*3*/ 1722a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The next 4 are for the bordered version. 1723a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1, +1, 0}, /*4*/ 1724a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1, +1, 0}, /*5*/ 1725a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1, -1, 0}, /*6*/ 1726a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1, -1, 0}, /*7*/ 1727a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1728a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Octagon that inscribes the unit circle, cut by an interior unit octagon. 1729a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.000000f, 0.000000f, 0}, /* 8*/ 1730a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.000000f, +0.414214f, ~0}, /* 9*/ 1731a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.707106f, +0.707106f, 0}, /*10*/ 1732a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.414214f, +1.000000f, ~0}, /*11*/ 1733a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.000000f, +1.000000f, 0}, /*12*/ 1734a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.414214f, +1.000000f, ~0}, /*13*/ 1735a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.707106f, +0.707106f, 0}, /*14*/ 1736a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.000000f, +0.414214f, ~0}, /*15*/ 1737a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.000000f, 0.000000f, 0}, /*16*/ 1738a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.000000f, -0.414214f, ~0}, /*17*/ 1739a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.707106f, -0.707106f, 0}, /*18*/ 1740a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.414214f, -1.000000f, ~0}, /*19*/ 1741a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.000000f, -1.000000f, 0}, /*20*/ 1742a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.414214f, -1.000000f, ~0}, /*21*/ 1743a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.707106f, -0.707106f, 0}, /*22*/ 1744a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.000000f, -0.414214f, ~0}, /*23*/ 1745a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // This vertex is for the fanned versions. 1746a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.000000f, 0.000000f, ~0}, /*24*/ 1747a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1748a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Rectangle with disjoint corner segments. 1749a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.0, +0.5, 0x3}, /*25*/ 1750a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.0, +1.0, 0x3}, /*26*/ 1751a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.5, +1.0, 0x3}, /*27*/ 1752a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.5, +1.0, 0x2}, /*28*/ 1753a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.0, +1.0, 0x2}, /*29*/ 1754a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.0, +0.5, 0x2}, /*30*/ 1755a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.0, -0.5, 0x0}, /*31*/ 1756a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.0, -1.0, 0x0}, /*32*/ 1757a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.5, -1.0, 0x0}, /*33*/ 1758a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.5, -1.0, 0x1}, /*34*/ 1759a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.0, -1.0, 0x1}, /*35*/ 1760a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.0, -0.5, 0x1}, /*36*/ 1761a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The next 4 are for the fanned version. 1762a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.0, 0.0, 0x3}, /*37*/ 1763a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.0, 0.0, 0x2}, /*38*/ 1764a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.0, 0.0, 0x0}, /*39*/ 1765a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.0, 0.0, 0x1}, /*40*/ 1766a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The next 8 are for the bordered version. 1767a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.75, +0.50, 0x3}, /*41*/ 1768a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.50, +0.75, 0x3}, /*42*/ 1769a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.50, +0.75, 0x2}, /*43*/ 1770a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.75, +0.50, 0x2}, /*44*/ 1771a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.75, -0.50, 0x0}, /*45*/ 1772a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.50, -0.75, 0x0}, /*46*/ 1773a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.50, -0.75, 0x1}, /*47*/ 1774a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.75, -0.50, 0x1}, /*48*/ 1775a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1776a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // 16-gon that inscribes the unit circle, cut by an interior unit 16-gon. 1777a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.000000f, +0.000000f, 0}, /*49*/ 1778a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.000000f, +0.198913f, ~0}, /*50*/ 1779a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.923879f, +0.382683f, 0}, /*51*/ 1780a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.847760f, +0.566455f, ~0}, /*52*/ 1781a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.707106f, +0.707106f, 0}, /*53*/ 1782a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.566455f, +0.847760f, ~0}, /*54*/ 1783a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.382683f, +0.923879f, 0}, /*55*/ 1784a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.198913f, +1.000000f, ~0}, /*56*/ 1785a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.000000f, +1.000000f, 0}, /*57*/ 1786a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.198913f, +1.000000f, ~0}, /*58*/ 1787a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.382683f, +0.923879f, 0}, /*59*/ 1788a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.566455f, +0.847760f, ~0}, /*60*/ 1789a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.707106f, +0.707106f, 0}, /*61*/ 1790a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.847760f, +0.566455f, ~0}, /*62*/ 1791a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.923879f, +0.382683f, 0}, /*63*/ 1792a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.000000f, +0.198913f, ~0}, /*64*/ 1793a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.000000f, +0.000000f, 0}, /*65*/ 1794a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.000000f, -0.198913f, ~0}, /*66*/ 1795a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.923879f, -0.382683f, 0}, /*67*/ 1796a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.847760f, -0.566455f, ~0}, /*68*/ 1797a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.707106f, -0.707106f, 0}, /*69*/ 1798a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.566455f, -0.847760f, ~0}, /*70*/ 1799a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.382683f, -0.923879f, 0}, /*71*/ 1800a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.198913f, -1.000000f, ~0}, /*72*/ 1801a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.000000f, -1.000000f, 0}, /*73*/ 1802a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.198913f, -1.000000f, ~0}, /*74*/ 1803a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.382683f, -0.923879f, 0}, /*75*/ 1804a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.566455f, -0.847760f, ~0}, /*76*/ 1805a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.707106f, -0.707106f, 0}, /*77*/ 1806a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.847760f, -0.566455f, ~0}, /*78*/ 1807a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.923879f, -0.382683f, 0}, /*79*/ 1808a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.000000f, -0.198913f, ~0}, /*80*/ 1809a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 1810a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1811a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst uint8_t kIndexData[] = { 1812a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Rectangle. 1813a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 0, 1, 2, 1814a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 0, 2, 3, 1815a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1816a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Rectangle with a border. 1817a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 0, 1, 5, 1818a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 5, 4, 0, 1819a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1, 2, 6, 1820a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 6, 5, 1, 1821a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2, 3, 7, 1822a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 7, 6, 2, 1823a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 3, 0, 4, 1824a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 4, 7, 3, 1825a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 4, 5, 6, 1826a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 6, 7, 4, 1827a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1828a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Octagon that inscribes the unit circle, cut by an interior unit octagon. 1829a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 10, 8, 9, 1830a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 12, 10, 11, 1831a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 14, 12, 13, 1832a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 16, 14, 15, 1833a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 18, 16, 17, 1834a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 20, 18, 19, 1835a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 22, 20, 21, 1836a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 8, 22, 23, 1837a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 8, 10, 12, 1838a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 12, 14, 16, 1839a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 16, 18, 20, 1840a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 20, 22, 8, 1841a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 8, 12, 16, 1842a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 16, 20, 8, 1843a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1844a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Same octagons, but with the interior arranged as a fan. Used by mixed samples. 1845a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 10, 8, 9, 1846a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 12, 10, 11, 1847a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 14, 12, 13, 1848a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 16, 14, 15, 1849a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 18, 16, 17, 1850a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 20, 18, 19, 1851a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 22, 20, 21, 1852a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 8, 22, 23, 1853a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 24, 8, 10, 1854a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 12, 24, 10, 1855a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 24, 12, 14, 1856a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 16, 24, 14, 1857a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 24, 16, 18, 1858a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 20, 24, 18, 1859a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 24, 20, 22, 1860a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 8, 24, 22, 1861a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1862a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Same octagons, but with the inner and outer disjoint. Used by coverage AA. 1863a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 8, 22, 23, 1864a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 9, 8, 23, 1865a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 10, 8, 9, 1866a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 11, 10, 9, 1867a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 12, 10, 11, 1868a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 13, 12, 11, 1869a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 14, 12, 13, 1870a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 15, 14, 13, 1871a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 16, 14, 15, 1872a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 17, 16, 15, 1873a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 18, 16, 17, 1874a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 19, 18, 17, 1875a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 20, 18, 19, 1876a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 21, 20, 19, 1877a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 22, 20, 21, 1878a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 23, 22, 21, 1879a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 22, 8, 10, 1880a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 10, 12, 14, 1881a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 14, 16, 18, 1882a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 18, 20, 22, 1883a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 22, 10, 14, 1884a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 14, 18, 22, 1885a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1886a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Rectangle with disjoint corner segments. 1887a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 27, 25, 26, 1888a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 30, 28, 29, 1889a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 33, 31, 32, 1890a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 36, 34, 35, 1891a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 25, 27, 28, 1892a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 28, 30, 31, 1893a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 31, 33, 34, 1894a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 34, 36, 25, 1895a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 25, 28, 31, 1896a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 31, 34, 25, 1897a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1898a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Same rectangle with disjoint corners, but with the interior arranged as a fan. Used by 1899a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // mixed samples. 1900a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 27, 25, 26, 1901a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 30, 28, 29, 1902a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 33, 31, 32, 1903a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 36, 34, 35, 1904a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 27, 37, 25, 1905a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 28, 37, 27, 1906a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 30, 38, 28, 1907a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 31, 38, 30, 1908a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 33, 39, 31, 1909a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 34, 39, 33, 1910a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 36, 40, 34, 1911a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 25, 40, 36, 1912a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1913a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Same rectangle with disjoint corners, with a border as well. Used by coverage AA. 1914a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 41, 25, 26, 1915a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 42, 41, 26, 1916a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 27, 42, 26, 1917a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 43, 28, 29, 1918a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 44, 43, 29, 1919a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 30, 44, 29, 1920a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 45, 31, 32, 1921a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 46, 45, 32, 1922a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 33, 46, 32, 1923a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 47, 34, 35, 1924a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 48, 47, 35, 1925a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 36, 48, 35, 1926a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 27, 28, 42, 1927a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 42, 28, 43, 1928a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 30, 31, 44, 1929a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 44, 31, 45, 1930a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 33, 34, 46, 1931a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 46, 34, 47, 1932a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 36, 25, 48, 1933a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 48, 25, 41, 1934a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 41, 42, 43, 1935a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 43, 44, 45, 1936a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 45, 46, 47, 1937a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 47, 48, 41, 1938a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 41, 43, 45, 1939a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 45, 47, 41, 1940a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1941a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Same as the disjoint octagons, but with 16-gons instead. Used by coverage AA when the oval is 1942a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // sufficiently large. 1943a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 49, 79, 80, 1944a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 50, 49, 80, 1945a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 51, 49, 50, 1946a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 52, 51, 50, 1947a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 53, 51, 52, 1948a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 54, 53, 52, 1949a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 55, 53, 54, 1950a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 56, 55, 54, 1951a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 57, 55, 56, 1952a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 58, 57, 56, 1953a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 59, 57, 58, 1954a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 60, 59, 58, 1955a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 61, 59, 60, 1956a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 62, 61, 60, 1957a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 63, 61, 62, 1958a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 64, 63, 62, 1959a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 65, 63, 64, 1960a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 66, 65, 64, 1961a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 67, 65, 66, 1962a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 68, 67, 66, 1963a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 69, 67, 68, 1964a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 70, 69, 68, 1965a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 71, 69, 70, 1966a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 72, 71, 70, 1967a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 73, 71, 72, 1968a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 74, 73, 72, 1969a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 75, 73, 74, 1970a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 76, 75, 74, 1971a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 77, 75, 76, 1972a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 78, 77, 76, 1973a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 79, 77, 78, 1974a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 80, 79, 78, 1975a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 49, 51, 53, 1976a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 53, 55, 57, 1977a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 57, 59, 61, 1978a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 61, 63, 65, 1979a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 65, 67, 69, 1980a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 69, 71, 73, 1981a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 73, 75, 77, 1982a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 77, 79, 49, 1983a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 49, 53, 57, 1984a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 57, 61, 65, 1985a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 65, 69, 73, 1986a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 73, 77, 49, 1987a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 49, 57, 65, 1988a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 65, 73, 49, 1989a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 1990a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1991a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonenum { 1992a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kRect_FirstIndex = 0, 1993a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kRect_TriCount = 2, 1994a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1995a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kFramedRect_FirstIndex = 6, 1996a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kFramedRect_TriCount = 10, 1997a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1998a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kOctagons_FirstIndex = 36, 1999a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kOctagons_TriCount = 14, 2000a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2001a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kOctagonsFanned_FirstIndex = 78, 2002a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kOctagonsFanned_TriCount = 16, 2003a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2004a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kDisjointOctagons_FirstIndex = 126, 2005a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kDisjointOctagons_TriCount = 22, 2006a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2007a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kCorneredRect_FirstIndex = 192, 2008a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kCorneredRect_TriCount = 10, 2009a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2010a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kCorneredRectFanned_FirstIndex = 222, 2011a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kCorneredRectFanned_TriCount = 12, 2012a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2013a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kCorneredFramedRect_FirstIndex = 258, 2014a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kCorneredFramedRect_TriCount = 26, 2015a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2016a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kDisjoint16Gons_FirstIndex = 336, 2017a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kDisjoint16Gons_TriCount = 46, 2018a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 2019a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2020a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGR_DECLARE_STATIC_UNIQUE_KEY(gShapeVertexBufferKey); 2021a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2022a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst GrBuffer* InstanceProcessor::FindOrCreateVertexBuffer(GrGpu* gpu) { 2023a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_DEFINE_STATIC_UNIQUE_KEY(gShapeVertexBufferKey); 2024a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrResourceCache* cache = gpu->getContext()->getResourceCache(); 2025a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (GrGpuResource* cached = cache->findAndRefUniqueResource(gShapeVertexBufferKey)) { 2026a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return static_cast<GrBuffer*>(cached); 2027a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 2028a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (GrBuffer* buffer = gpu->createBuffer(sizeof(kVertexData), kVertex_GrBufferType, 2029a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kStatic_GrAccessPattern, kVertexData)) { 2030a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton buffer->resourcePriv().setUniqueKey(gShapeVertexBufferKey); 2031a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return buffer; 2032a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 2033a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return nullptr; 2034a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2035a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2036a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGR_DECLARE_STATIC_UNIQUE_KEY(gShapeIndexBufferKey); 2037a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2038a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst GrBuffer* InstanceProcessor::FindOrCreateIndex8Buffer(GrGpu* gpu) { 2039a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_DEFINE_STATIC_UNIQUE_KEY(gShapeIndexBufferKey); 2040a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrResourceCache* cache = gpu->getContext()->getResourceCache(); 2041a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (GrGpuResource* cached = cache->findAndRefUniqueResource(gShapeIndexBufferKey)) { 2042a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return static_cast<GrBuffer*>(cached); 2043a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 2044a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (GrBuffer* buffer = gpu->createBuffer(sizeof(kIndexData), kIndex_GrBufferType, 2045a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kStatic_GrAccessPattern, kIndexData)) { 2046a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton buffer->resourcePriv().setUniqueKey(gShapeIndexBufferKey); 2047a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return buffer; 2048a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 2049a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return nullptr; 2050a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2051a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2052a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonIndexRange InstanceProcessor::GetIndexRangeForRect(AntialiasMode aa) { 2053a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton static constexpr IndexRange kRectRanges[kNumAntialiasModes] = { 2054a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {kRect_FirstIndex, 3 * kRect_TriCount}, // kNone 2055a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {kFramedRect_FirstIndex, 3 * kFramedRect_TriCount}, // kCoverage 2056a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {kRect_FirstIndex, 3 * kRect_TriCount}, // kMSAA 2057a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {kRect_FirstIndex, 3 * kRect_TriCount} // kMixedSamples 2058a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton }; 2059a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2060a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(aa >= AntialiasMode::kNone && aa <= AntialiasMode::kMixedSamples); 2061a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return kRectRanges[(int)aa]; 2062a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2063a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(0 == (int)AntialiasMode::kNone); 2064a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(1 == (int)AntialiasMode::kCoverage); 2065a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(2 == (int)AntialiasMode::kMSAA); 2066a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(3 == (int)AntialiasMode::kMixedSamples); 2067a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2068a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2069a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonIndexRange InstanceProcessor::GetIndexRangeForOval(AntialiasMode aa, const SkRect& devBounds) { 2070a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (AntialiasMode::kCoverage == aa && devBounds.height() * devBounds.width() >= 256 * 256) { 2071a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // This threshold was chosen quasi-scientifically on Tegra X1. 2072a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return {kDisjoint16Gons_FirstIndex, 3 * kDisjoint16Gons_TriCount}; 2073a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 2074a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2075a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton static constexpr IndexRange kOvalRanges[kNumAntialiasModes] = { 2076a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {kOctagons_FirstIndex, 3 * kOctagons_TriCount}, // kNone 2077a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {kDisjointOctagons_FirstIndex, 3 * kDisjointOctagons_TriCount}, // kCoverage 2078a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {kOctagons_FirstIndex, 3 * kOctagons_TriCount}, // kMSAA 2079a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {kOctagonsFanned_FirstIndex, 3 * kOctagonsFanned_TriCount} // kMixedSamples 2080a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton }; 2081a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2082a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(aa >= AntialiasMode::kNone && aa <= AntialiasMode::kMixedSamples); 2083a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return kOvalRanges[(int)aa]; 2084a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2085a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(0 == (int)AntialiasMode::kNone); 2086a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(1 == (int)AntialiasMode::kCoverage); 2087a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(2 == (int)AntialiasMode::kMSAA); 2088a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(3 == (int)AntialiasMode::kMixedSamples); 2089a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2090a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2091a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonIndexRange InstanceProcessor::GetIndexRangeForRRect(AntialiasMode aa) { 2092a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton static constexpr IndexRange kRRectRanges[kNumAntialiasModes] = { 2093a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {kCorneredRect_FirstIndex, 3 * kCorneredRect_TriCount}, // kNone 2094a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {kCorneredFramedRect_FirstIndex, 3 * kCorneredFramedRect_TriCount}, // kCoverage 2095a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {kCorneredRect_FirstIndex, 3 * kCorneredRect_TriCount}, // kMSAA 2096a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {kCorneredRectFanned_FirstIndex, 3 * kCorneredRectFanned_TriCount} // kMixedSamples 2097a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton }; 2098a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2099a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(aa >= AntialiasMode::kNone && aa <= AntialiasMode::kMixedSamples); 2100a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return kRRectRanges[(int)aa]; 2101a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2102a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(0 == (int)AntialiasMode::kNone); 2103a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(1 == (int)AntialiasMode::kCoverage); 2104a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(2 == (int)AntialiasMode::kMSAA); 2105a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_STATIC_ASSERT(3 == (int)AntialiasMode::kMixedSamples); 2106a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2107a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2108a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst char* InstanceProcessor::GetNameOfIndexRange(IndexRange range) { 2109a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton switch (range.fStart) { 2110a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kRect_FirstIndex: return "basic_rect"; 2111a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kFramedRect_FirstIndex: return "coverage_rect"; 2112a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2113a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kOctagons_FirstIndex: return "basic_oval"; 2114a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kDisjointOctagons_FirstIndex: return "coverage_oval"; 2115a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kDisjoint16Gons_FirstIndex: return "coverage_large_oval"; 2116a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kOctagonsFanned_FirstIndex: return "mixed_samples_oval"; 2117a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2118a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kCorneredRect_FirstIndex: return "basic_round_rect"; 2119a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kCorneredFramedRect_FirstIndex: return "coverage_round_rect"; 2120a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kCorneredRectFanned_FirstIndex: return "mixed_samples_round_rect"; 2121a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2122a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton default: return "unknown"; 2123a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 2124a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2125a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2126a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2127