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