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 70af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon if (GrAATypeIsHW(fOpInfo.aaType())) { 71af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon if (!fOpInfo.isSimpleRects() || GrAAType::kMixedSamples == fOpInfo.aaType()) { 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()); 11884645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas switch (type) { 11984645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas case kVec2f_GrSLType: // fall through 12084645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas case kVec3f_GrSLType: // fall through 12184645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas case kVec4f_GrSLType: 12284645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas break; 12384645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas default: 12484645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas fVertexBuilder->codeAppendf("%s(", GrGLSLTypeString(type)); 125a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 126a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fVertexBuilder->appendTexelFetch(fParamsBuffer, "paramsIdx++"); 12784645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas switch (type) { 12884645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas case kVec2f_GrSLType: 12984645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas fVertexBuilder->codeAppend(".xy"); 13084645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas break; 13184645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas case kVec3f_GrSLType: 13284645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas fVertexBuilder->codeAppend(".xyz"); 13384645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas break; 13484645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas case kVec4f_GrSLType: 13584645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas break; 13684645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas default: 13784645e3c679581d191406b2d7ab93c3f6c5e3a63Ethan Nicholas fVertexBuilder->codeAppend(")"); 138a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 139a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 140a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 141a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void skipParams(unsigned n) const { 142a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(fParamsBuffer.isValid()); 143a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fVertexBuilder->codeAppendf("paramsIdx += %u;", n); 144a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 145a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 146a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate: 147a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const InstanceProcessor& fInstProc; 148a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* fVertexBuilder; 149a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SamplerHandle fParamsBuffer; 150a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 151a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 152a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::Backend { 153a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic: 15499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon static Backend* SK_WARN_UNUSED_RESULT Create(const GrPipeline&, OpInfo, const VertexInputs&); 155a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual ~Backend() {} 156a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 157a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void init(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*); 158a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void setupRect(GrGLSLVertexBuilder*) = 0; 159a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void setupOval(GrGLSLVertexBuilder*) = 0; 1600caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton void setupRRect(GrGLSLVertexBuilder*, int* usedShapeDefinitions); 161a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 162a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void initInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*); 163a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void setupInnerRect(GrGLSLVertexBuilder*) = 0; 164a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void setupInnerOval(GrGLSLVertexBuilder*) = 0; 1650caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton void setupInnerSimpleRRect(GrGLSLVertexBuilder*); 166a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 167a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outShapeCoords() { 168a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return fModifiedShapeCoords ? fModifiedShapeCoords : fInputs.attr(Attrib::kShapeCoords); 169a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 170a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 171a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char* outCoverage, 172a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outColor); 173a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 174a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprotected: 17599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon Backend(OpInfo opInfo, const VertexInputs& inputs) 17699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon : fOpInfo(opInfo) 17799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fInputs(inputs) 17899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fModifiesCoverage(false) 17999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fModifiesColor(false) 18099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fNeedsNeighborRadii(false) 18199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fColor(kVec4f_GrSLType) 18299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fTriangleIsArc(kInt_GrSLType) 18399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fArcCoords(kVec2f_GrSLType) 18499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fInnerShapeCoords(kVec2f_GrSLType) 18599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fInnerRRect(kVec4f_GrSLType) 18699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fModifiedShapeCoords(nullptr) { 18799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (fOpInfo.fShapeTypes & kRRect_ShapesMask) { 188a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiedShapeCoords = "adjustedShapeCoords"; 189a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 190a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 191a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 192a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) = 0; 193a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void adjustRRectVertices(GrGLSLVertexBuilder*); 194a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void onSetupRRect(GrGLSLVertexBuilder*) {} 195a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 196a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) = 0; 1970caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton virtual void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) = 0; 198a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 199a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton virtual void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, 200a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage, const char* outColor) = 0; 201a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 202a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupSimpleRadii(GrGLSLVertexBuilder*); 203a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupNinePatchRadii(GrGLSLVertexBuilder*); 204a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupComplexRadii(GrGLSLVertexBuilder*); 205a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 20699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon const OpInfo fOpInfo; 20799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon const VertexInputs& fInputs; 20899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon bool fModifiesCoverage; 20999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon bool fModifiesColor; 21099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon bool fNeedsNeighborRadii; 21199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon GrGLSLVertToFrag fColor; 21299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon GrGLSLVertToFrag fTriangleIsArc; 21399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon GrGLSLVertToFrag fArcCoords; 21499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon GrGLSLVertToFrag fInnerShapeCoords; 21599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon GrGLSLVertToFrag fInnerRRect; 21699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon const char* fModifiedShapeCoords; 217a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 218a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 219a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { 220a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const GrPipeline& pipeline = args.fVertBuilder->getProgramBuilder()->pipeline(); 221a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const InstanceProcessor& ip = args.fGP.cast<InstanceProcessor>(); 222a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLUniformHandler* uniHandler = args.fUniformHandler; 223a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; 224a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v = args.fVertBuilder; 225a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLPPFragmentBuilder* f = args.fFragBuilder; 226a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 227a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->emitAttributes(ip); 228a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 229a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton VertexInputs inputs(ip, v); 23099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fHasParams) { 231a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(1 == ip.numBuffers()); 232a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.initParams(args.fBufferSamplers[0]); 233a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 234a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 23599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!ip.opInfo().fHasPerspective) { 236a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("mat2x3 shapeMatrix = mat2x3(%s, %s);", 237a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY)); 238a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 2395961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas v->defineConstantf("int", "PERSPECTIVE_FLAG", "0x%x", kPerspective_InfoFlag); 240a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("mat3 shapeMatrix = mat3(%s, %s, vec3(0, 0, 1));", 241a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY)); 2425961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas v->codeAppendf("if (0 != (%s & PERSPECTIVE_FLAG)) {", 243a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kInstanceInfo)); 244a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( "shapeMatrix[2] = "); 245a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.fetchNextParam(kVec3f_GrSLType); 246a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( ";"); 247a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("}"); 248a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 249a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 25099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon bool hasSingleShapeType = SkIsPow2(ip.opInfo().fShapeTypes); 251a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!hasSingleShapeType) { 2525961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas v->defineConstant("SHAPE_TYPE_BIT", kShapeType_InfoBit); 253a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("uint shapeType = %s >> SHAPE_TYPE_BIT;", 254a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kInstanceInfo)); 255a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 256a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 25799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon std::unique_ptr<Backend> backend(Backend::Create(pipeline, ip.opInfo(), inputs)); 258a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->init(varyingHandler, v); 259a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2600caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton int usedShapeDefinitions = 0; 2610caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton 26299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (hasSingleShapeType || !(ip.opInfo().fShapeTypes & ~kRRect_ShapesMask)) { 26399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kRect_ShapeFlag == ip.opInfo().fShapeTypes) { 264a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->setupRect(v); 26599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon } else if (kOval_ShapeFlag == ip.opInfo().fShapeTypes) { 266a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->setupOval(v); 267a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 2680caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton backend->setupRRect(v, &usedShapeDefinitions); 269a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 270a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 27199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fShapeTypes & kRRect_ShapesMask) { 2720caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("if (shapeType >= SIMPLE_R_RECT_SHAPE_TYPE) {"); 2730caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton backend->setupRRect(v, &usedShapeDefinitions); 2740caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("}"); 2750caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton usedShapeDefinitions |= kSimpleRRect_ShapeFlag; 276a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 27799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fShapeTypes & kOval_ShapeFlag) { 27899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fShapeTypes & kRect_ShapeFlag) { 27999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fShapeTypes & kRRect_ShapesMask) { 2800caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else "); 2810caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 2820caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("if (OVAL_SHAPE_TYPE == shapeType) {"); 2830caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton usedShapeDefinitions |= kOval_ShapeFlag; 2840caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } else { 2850caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else {"); 2860caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 287a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->setupOval(v); 2880caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("}"); 289a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 29099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fShapeTypes & kRect_ShapeFlag) { 2910caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else {"); 2920caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton backend->setupRect(v); 2930caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("}"); 294a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 295a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 296a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 29799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fInnerShapeTypes) { 29899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon bool hasSingleInnerShapeType = SkIsPow2(ip.opInfo().fInnerShapeTypes); 299a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!hasSingleInnerShapeType) { 3005961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas v->defineConstantf("int", "INNER_SHAPE_TYPE_MASK", "0x%x", kInnerShapeType_InfoMask); 3015961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas v->defineConstant("INNER_SHAPE_TYPE_BIT", kInnerShapeType_InfoBit); 302a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("uint innerShapeType = ((%s & INNER_SHAPE_TYPE_MASK) >> " 303a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "INNER_SHAPE_TYPE_BIT);", 304a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kInstanceInfo)); 305a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 306a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Here we take advantage of the fact that outerRect == localRect in recordDRRect. 307a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec4 outer = %s;", inputs.attr(Attrib::kLocalRect)); 308a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec4 inner = "); 309a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.fetchNextParam(); 310a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend (";"); 311a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // outer2Inner is a transform from shape coords to inner shape coords: 312a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // e.g. innerShapeCoords = shapeCoords * outer2Inner.xy + outer2Inner.zw 313a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec4 outer2Inner = vec4(outer.zw - outer.xy, " 314a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "outer.xy + outer.zw - inner.xy - inner.zw) / " 315a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "(inner.zw - inner.xy).xyxy;"); 316a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 innerShapeCoords = %s * outer2Inner.xy + outer2Inner.zw;", 317a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->outShapeCoords()); 318a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 319a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->initInnerShape(varyingHandler, v); 320a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 32199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon SkASSERT(0 == (ip.opInfo().fInnerShapeTypes & kRRect_ShapesMask) || 32299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon kSimpleRRect_ShapeFlag == (ip.opInfo().fInnerShapeTypes & kRRect_ShapesMask)); 3230caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton 324a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (hasSingleInnerShapeType) { 32599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kRect_ShapeFlag == ip.opInfo().fInnerShapeTypes) { 326a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->setupInnerRect(v); 32799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon } else if (kOval_ShapeFlag == ip.opInfo().fInnerShapeTypes) { 328a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->setupInnerOval(v); 329a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 3300caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton backend->setupInnerSimpleRRect(v); 331a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 332a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 33399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) { 3340caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == innerShapeType) {"); 3350caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton backend->setupInnerSimpleRRect(v); 3360caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend("}"); 3370caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton usedShapeDefinitions |= kSimpleRRect_ShapeFlag; 338a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 33999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fInnerShapeTypes & kOval_ShapeFlag) { 34099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fInnerShapeTypes & kRect_ShapeFlag) { 34199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) { 3420caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else "); 3430caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 3440caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("if (OVAL_SHAPE_TYPE == innerShapeType) {"); 3450caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton usedShapeDefinitions |= kOval_ShapeFlag; 3460caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } else { 3470caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else {"); 3480caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 349a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton backend->setupInnerOval(v); 3500caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend("}"); 351a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 35299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fInnerShapeTypes & kRect_ShapeFlag) { 3530caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend("else {"); 3540caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton backend->setupInnerRect(v); 3550caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend("}"); 356a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 357a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 358a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 359a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 3600caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (usedShapeDefinitions & kOval_ShapeFlag) { 3615961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas v->defineConstant("OVAL_SHAPE_TYPE", (int)ShapeType::kOval); 362a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 3630caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (usedShapeDefinitions & kSimpleRRect_ShapeFlag) { 3645961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas v->defineConstant("SIMPLE_R_RECT_SHAPE_TYPE", (int)ShapeType::kSimpleRRect); 3650caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 3660caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (usedShapeDefinitions & kNinePatch_ShapeFlag) { 3675961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas v->defineConstant("NINE_PATCH_SHAPE_TYPE", (int)ShapeType::kNinePatch); 3680caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 3690caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton SkASSERT(!(usedShapeDefinitions & (kRect_ShapeFlag | kComplexRRect_ShapeFlag))); 370a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 3718c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon backend->emitCode(v, f, args.fOutputCoverage, args.fOutputColor); 372a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 373a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* localCoords = nullptr; 37499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fUsesLocalCoords) { 375a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton localCoords = "localCoords"; 376a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 t = 0.5 * (%s + vec2(1));", backend->outShapeCoords()); 377a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 localCoords = (1.0 - t) * %s.xy + t * %s.zw;", 378a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kLocalRect), inputs.attr(Attrib::kLocalRect)); 379a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 38099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (ip.opInfo().fHasLocalMatrix && ip.opInfo().fHasParams) { 3815961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas v->defineConstantf("int", "LOCAL_MATRIX_FLAG", "0x%x", kLocalMatrix_InfoFlag); 3825961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas v->codeAppendf("if (0 != (%s & LOCAL_MATRIX_FLAG)) {", 383a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.attr(Attrib::kInstanceInfo)); 38499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!ip.opInfo().fUsesLocalCoords) { 385a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.skipParams(2); 386a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 387a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf( "mat2x3 localMatrix;"); 388a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( "localMatrix[0] = "); 389a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.fetchNextParam(kVec3f_GrSLType); 390a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( ";"); 391a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( "localMatrix[1] = "); 392a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton inputs.fetchNextParam(kVec3f_GrSLType); 393a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( ";"); 394a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ( "localCoords = (vec3(localCoords, 1) * localMatrix).xy;"); 395a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 396a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("}"); 397a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 398a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 39999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon GrSLType positionType = ip.opInfo().fHasPerspective ? kVec3f_GrSLType : kVec2f_GrSLType; 400a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s deviceCoords = vec3(%s, 1) * shapeMatrix;", 401a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLTypeString(positionType), backend->outShapeCoords()); 402a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton gpArgs->fPositionVar.set(positionType, "deviceCoords"); 403a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 404a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitTransforms(v, varyingHandler, uniHandler, gpArgs->fPositionVar, localCoords, 405a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon args.fFPCoordTransformHandler); 406a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 407a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 408a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton//////////////////////////////////////////////////////////////////////////////////////////////////// 409a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 410a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::init(GrGLSLVaryingHandler* varyingHandler, 411a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v) { 412a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fModifiedShapeCoords) { 413a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 %s = %s;", fModifiedShapeCoords, fInputs.attr(Attrib::kShapeCoords)); 414a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 415a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 416a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->onInit(varyingHandler, v); 417a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 418a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fColor.vsOut()) { 419a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("color", &fColor, kLow_GrSLPrecision); 420a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s;", fColor.vsOut(), fInputs.attr(Attrib::kColor)); 421a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 422a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 423a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 4240caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::Backend::setupRRect(GrGLSLVertexBuilder* v, int* usedShapeDefinitions) { 425a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("uvec2 corner = uvec2(%s & 1, (%s >> 1) & 1);", 426a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kVertexAttrs), fInputs.attr(Attrib::kVertexAttrs)); 427a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 cornerSign = vec2(corner) * 2.0 - 1.0;"); 428a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 radii%s;", fNeedsNeighborRadii ? ", neighborRadii" : ""); 429a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("mat2 p = "); 430a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.fetchNextParam(kMat22f_GrSLType); 431a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend (";"); 43299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon uint8_t types = fOpInfo.fShapeTypes & kRRect_ShapesMask; 433a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (0 == (types & (types - 1))) { 434a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (kSimpleRRect_ShapeFlag == types) { 435a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->setupSimpleRadii(v); 436a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (kNinePatch_ShapeFlag == types) { 437a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->setupNinePatchRadii(v); 438a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (kComplexRRect_ShapeFlag == types) { 439a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->setupComplexRadii(v); 440a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 441a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 442a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (types & kSimpleRRect_ShapeFlag) { 4430caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == shapeType) {"); 444a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->setupSimpleRadii(v); 4450caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("}"); 4460caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton *usedShapeDefinitions |= kSimpleRRect_ShapeFlag; 447a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 448a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (types & kNinePatch_ShapeFlag) { 4490caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (types & kComplexRRect_ShapeFlag) { 4500caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton if (types & kSimpleRRect_ShapeFlag) { 4510caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else "); 4520caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 4530caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("if (NINE_PATCH_SHAPE_TYPE == shapeType) {"); 4540caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton *usedShapeDefinitions |= kNinePatch_ShapeFlag; 4550caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } else { 4560caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else {"); 4570caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton } 458a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->setupNinePatchRadii(v); 4590caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("}"); 460a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 461a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (types & kComplexRRect_ShapeFlag) { 4620caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("else {"); 463a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->setupComplexRadii(v); 4640caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton v->codeAppend ("}"); 465a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 466a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 467a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 468a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->adjustRRectVertices(v); 469a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 470a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fArcCoords.vsOut()) { 471a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = (cornerSign * %s + radii - vec2(1)) / radii;", 472a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcCoords.vsOut(), fModifiedShapeCoords); 473a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 474a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.vsOut()) { 475a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = int(all(equal(vec2(1), abs(%s))));", 476a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kShapeCoords)); 477a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 478a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 479a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->onSetupRRect(v); 480a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 481a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 482a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::setupSimpleRadii(GrGLSLVertexBuilder* v) { 483a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fNeedsNeighborRadii) { 484a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("neighborRadii = "); 485a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 486a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("radii = p[0] * 2.0 / p[1];"); 487a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 488a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 489a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::setupNinePatchRadii(GrGLSLVertexBuilder* v) { 490a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("radii = vec2(p[0][corner.x], p[1][corner.y]);"); 491a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fNeedsNeighborRadii) { 492a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("neighborRadii = vec2(p[0][1u - corner.x], p[1][1u - corner.y]);"); 493a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 494a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 495a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 496a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::setupComplexRadii(GrGLSLVertexBuilder* v) { 497a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton /** 498a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * The x and y radii of each arc are stored in separate vectors, 499a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * in the following order: 500a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * 501a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * __x1 _ _ _ x3__ 502a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * 503a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * y1 | | y2 504a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * 505a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * | | 506a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * 507a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * y3 |__ _ _ _ __| y4 508a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * x2 x4 509a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton * 510a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton */ 511a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("mat2 p2 = "); 512a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.fetchNextParam(kMat22f_GrSLType); 513a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend(";"); 514a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("radii = vec2(p[corner.x][corner.y], p2[corner.y][corner.x]);"); 515a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fNeedsNeighborRadii) { 516a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("neighborRadii = vec2(p[1u - corner.x][corner.y], " 517a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "p2[1u - corner.y][corner.x]);"); 518a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 519a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 520a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 521a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::adjustRRectVertices(GrGLSLVertexBuilder* v) { 522a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Resize the 4 triangles that arcs are drawn into so they match their corresponding radii. 523a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // 0.5 is a special value that indicates the edge of an arc triangle. 524a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.x) == 0.5)" 525a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "%s.x = cornerSign.x * (1.0 - radii.x);", 526a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords); 527a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.y) == 0.5) " 528a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "%s.y = cornerSign.y * (1.0 - radii.y);", 529a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords); 530a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 531a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 532a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::initInnerShape(GrGLSLVaryingHandler* varyingHandler, 533a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v) { 53499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon SkASSERT(!(fOpInfo.fInnerShapeTypes & (kNinePatch_ShapeFlag | kComplexRRect_ShapeFlag))); 535a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 536a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->onInitInnerShape(varyingHandler, v); 537a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 538a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerShapeCoords.vsOut()) { 539a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = innerShapeCoords;", fInnerShapeCoords.vsOut()); 540a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 541a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 542a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 5430caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::Backend::setupInnerSimpleRRect(GrGLSLVertexBuilder* v) { 544a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("mat2 innerP = "); 545a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.fetchNextParam(kMat22f_GrSLType); 546a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend(";"); 547a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("vec2 innerRadii = innerP[0] * 2.0 / innerP[1];"); 5480caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton this->onSetupInnerSimpleRRect(v); 549a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 550a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 551a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::Backend::emitCode(GrGLSLVertexBuilder* v, GrGLSLPPFragmentBuilder* f, 552a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage, const char* outColor) { 553a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!fModifiesCoverage || outCoverage); 554a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->onEmitCode(v, f, fModifiesCoverage ? outCoverage : nullptr, 555a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiesColor ? outColor : nullptr); 556a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (outCoverage && !fModifiesCoverage) { 557a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Even though the subclass doesn't use coverage, we are expected to assign some value. 558a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = vec4(1);", outCoverage); 559a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 560a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fModifiesColor) { 561a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The subclass didn't assign a value to the output color. 562a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = %s;", outColor, fColor.fsIn()); 563a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 564a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 565a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 566a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton//////////////////////////////////////////////////////////////////////////////////////////////////// 567a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 568a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::BackendNonAA : public Backend { 569a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic: 57099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon BackendNonAA(OpInfo opInfo, const VertexInputs& inputs) : INHERITED(opInfo, inputs) { 57199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (fOpInfo.fCannotDiscard && !fOpInfo.isSimpleRects()) { 57299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon fModifiesColor = !fOpInfo.fCannotTweakAlphaForCoverage; 573a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiesCoverage = !fModifiesColor; 574a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 575a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 576a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 577a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate: 578a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override; 579a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupRect(GrGLSLVertexBuilder*) override; 580a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupOval(GrGLSLVertexBuilder*) override; 581a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 582a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override; 583a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupInnerRect(GrGLSLVertexBuilder*) override; 584a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupInnerOval(GrGLSLVertexBuilder*) override; 5850caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override; 586a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 587a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char*, 588a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char*) override; 589a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 590a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton typedef Backend INHERITED; 591a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 592a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 593a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onInit(GrGLSLVaryingHandler* varyingHandler, 594a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder*) { 59599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kRect_ShapeFlag != fOpInfo.fShapeTypes) { 596dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision); 597a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("arcCoords", &fArcCoords, kMedium_GrSLPrecision); 598a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 599a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 600a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 601a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupRect(GrGLSLVertexBuilder* v) { 602a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.vsOut()) { 603a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut()); 604a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 605a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 606a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 607a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupOval(GrGLSLVertexBuilder* v) { 608a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(fArcCoords.vsOut()); 609a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(fTriangleIsArc.vsOut()); 610a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s;", fArcCoords.vsOut(), this->outShapeCoords()); 611a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s & 1;", fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs)); 612a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 613a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 614a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler, 615a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder*) { 616a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords, kMedium_GrSLPrecision); 61799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kRect_ShapeFlag != fOpInfo.fInnerShapeTypes && 61899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon kOval_ShapeFlag != fOpInfo.fInnerShapeTypes) { 619a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kMedium_GrSLPrecision); 620a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 621a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 622a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 623a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupInnerRect(GrGLSLVertexBuilder* v) { 624a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerRRect.vsOut()) { 625a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(1);", fInnerRRect.vsOut()); 626a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 627a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 628a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 629a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::setupInnerOval(GrGLSLVertexBuilder* v) { 630a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerRRect.vsOut()) { 631a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(0, 0, 1, 1);", fInnerRRect.vsOut()); 632a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 633a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 634a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 6350caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) { 636a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(1.0 - innerRadii, 1.0 / innerRadii);", fInnerRRect.vsOut()); 637a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 638a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 639a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendNonAA::onEmitCode(GrGLSLVertexBuilder*, 640a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLPPFragmentBuilder* f, 641a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage, 642a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outColor) { 643a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* dropFragment = nullptr; 64499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!fOpInfo.fCannotDiscard) { 645a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton dropFragment = "discard"; 646a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fModifiesCoverage) { 6471fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppend ("lowp float covered = 1.0;"); 648a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton dropFragment = "covered = 0.0"; 649a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fModifiesColor) { 6501fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("lowp vec4 color = %s;", fColor.fsIn()); 651a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton dropFragment = "color = vec4(0)"; 652a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 653a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.fsIn()) { 654a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(dropFragment); 655a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s != 0 && dot(%s, %s) > 1.0) %s;", 656a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fTriangleIsArc.fsIn(), fArcCoords.fsIn(), fArcCoords.fsIn(), dropFragment); 657a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 65899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (fOpInfo.fInnerShapeTypes) { 659a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(dropFragment); 660a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("// Inner shape.\n"); 66199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kRect_ShapeFlag == fOpInfo.fInnerShapeTypes) { 662a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (all(lessThanEqual(abs(%s), vec2(1)))) %s;", 663a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeCoords.fsIn(), dropFragment); 66499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon } else if (kOval_ShapeFlag == fOpInfo.fInnerShapeTypes) { 665a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if ((dot(%s, %s) <= 1.0)) %s;", 666a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeCoords.fsIn(), fInnerShapeCoords.fsIn(), dropFragment); 667a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 668a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (all(lessThan(abs(%s), vec2(1)))) {", fInnerShapeCoords.fsIn()); 669a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "vec2 distanceToArcEdge = abs(%s) - %s.xy;", 670a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeCoords.fsIn(), fInnerRRect.fsIn()); 671a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "if (any(lessThan(distanceToArcEdge, vec2(0)))) {"); 672a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "%s;", dropFragment); 673a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "} else {"); 674a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "vec2 rrectCoords = distanceToArcEdge * %s.zw;", 675a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerRRect.fsIn()); 676a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "if (dot(rrectCoords, rrectCoords) <= 1.0) {"); 677a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "%s;", dropFragment); 678a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "}"); 679a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "}"); 680a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 681a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 682a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 683a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fModifiesCoverage) { 684a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = vec4(covered);", outCoverage); 685a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fModifiesColor) { 686a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = color;", outColor); 687a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 688a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 689a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 690a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton//////////////////////////////////////////////////////////////////////////////////////////////////// 691a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 692a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::BackendCoverage : public Backend { 693a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic: 69499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon BackendCoverage(OpInfo opInfo, const VertexInputs& inputs) 69599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon : INHERITED(opInfo, inputs) 69699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fColorTimesRectCoverage(kVec4f_GrSLType) 69799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fRectCoverage(kFloat_GrSLType) 69899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fEllipseCoords(kVec2f_GrSLType) 69999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fEllipseName(kVec2f_GrSLType) 70099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fBloatedRadius(kFloat_GrSLType) 70199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fDistanceToInnerEdge(kVec2f_GrSLType) 70299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fInnerShapeBloatedHalfSize(kVec2f_GrSLType) 70399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fInnerEllipseCoords(kVec2f_GrSLType) 70499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fInnerEllipseName(kVec2f_GrSLType) { 70599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon fShapeIsCircle = !fOpInfo.fNonSquare && !(fOpInfo.fShapeTypes & kRRect_ShapesMask); 70699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon fTweakAlphaForCoverage = !fOpInfo.fCannotTweakAlphaForCoverage && !fOpInfo.fInnerShapeTypes; 707a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiesCoverage = !fTweakAlphaForCoverage; 708a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiesColor = fTweakAlphaForCoverage; 709a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fModifiedShapeCoords = "bloatedShapeCoords"; 710a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 711a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 712a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate: 713a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override; 714a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupRect(GrGLSLVertexBuilder*) override; 715a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupOval(GrGLSLVertexBuilder*) override; 716a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void adjustRRectVertices(GrGLSLVertexBuilder*) override; 717a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onSetupRRect(GrGLSLVertexBuilder*) override; 718a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 719a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override; 720a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupInnerRect(GrGLSLVertexBuilder*) override; 721a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupInnerOval(GrGLSLVertexBuilder*) override; 7220caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override; 723a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 724a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char* outCoverage, 725a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outColor) override; 726a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 727a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitRect(GrGLSLPPFragmentBuilder*, const char* outCoverage, const char* outColor); 728a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitCircle(GrGLSLPPFragmentBuilder*, const char* outCoverage); 729a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitArc(GrGLSLPPFragmentBuilder* f, const char* ellipseCoords, const char* ellipseName, 730a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool ellipseCoordsNeedClamp, bool ellipseCoordsMayBeNegative, 731a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage); 732a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitInnerRect(GrGLSLPPFragmentBuilder*, const char* outCoverage); 733a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 734a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fColorTimesRectCoverage; 735a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fRectCoverage; 736a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fEllipseCoords; 737a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fEllipseName; 738a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fBloatedRadius; 739a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fDistanceToInnerEdge; 740a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fInnerShapeBloatedHalfSize; 741a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fInnerEllipseCoords; 742a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fInnerEllipseName; 743a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fShapeIsCircle; 744a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fTweakAlphaForCoverage; 745a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 746a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton typedef Backend INHERITED; 747a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 748a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 749a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onInit(GrGLSLVaryingHandler* varyingHandler, 750a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v) { 751a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("mat2 shapeTransposeMatrix = transpose(mat2(shapeMatrix));"); 752a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 shapeHalfSize = vec2(length(shapeTransposeMatrix[0]), " 753a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "length(shapeTransposeMatrix[1]));"); 754a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 bloat = 0.5 / shapeHalfSize;"); 755a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("bloatedShapeCoords = %s * (1.0 + bloat);", fInputs.attr(Attrib::kShapeCoords)); 756a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 75799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kOval_ShapeFlag != fOpInfo.fShapeTypes) { 758a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTweakAlphaForCoverage) { 759a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("colorTimesRectCoverage", &fColorTimesRectCoverage, 760a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kLow_GrSLPrecision); 76199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kRect_ShapeFlag == fOpInfo.fShapeTypes) { 762a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fColor = fColorTimesRectCoverage; 763a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 764a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 765a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("rectCoverage", &fRectCoverage, kLow_GrSLPrecision); 766a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 767a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("float rectCoverage = 0.0;"); 768a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 76999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kRect_ShapeFlag != fOpInfo.fShapeTypes) { 770dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision); 771a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!fShapeIsCircle) { 772dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addVarying("ellipseCoords", &fEllipseCoords, kMedium_GrSLPrecision); 773a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("ellipseName", &fEllipseName, kHigh_GrSLPrecision); 774a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 775e0d362929d6569e8737d80dead791c640390e819csmartdalton varyingHandler->addVarying("circleCoords", &fEllipseCoords, kHigh_GrSLPrecision); 776e0d362929d6569e8737d80dead791c640390e819csmartdalton varyingHandler->addFlatVarying("bloatedRadius", &fBloatedRadius, kHigh_GrSLPrecision); 777a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 778a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 779a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 780a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 781a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupRect(GrGLSLVertexBuilder* v) { 782a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Make the border one pixel wide. Inner vs outer is indicated by coordAttrs. 783a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 rectBloat = (%s != 0) ? bloat : -bloat;", 784a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kVertexAttrs)); 785a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Here we use the absolute value, because when the rect is thinner than a pixel, this makes it 786a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // mark the spot where pixel center is within half a pixel of the *opposite* edge. This, 787a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // combined with the "maxCoverage" logic below gives us mathematically correct coverage even for 788a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // subpixel rectangles. 789a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("bloatedShapeCoords = %s * abs(vec2(1.0 + rectBloat));", 790a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords)); 791a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 792a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Determine coverage at the vertex. Coverage naturally ramps from 0 to 1 unless the rect is 793a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // narrower than a pixel. 794a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("float maxCoverage = 4.0 * min(0.5, shapeHalfSize.x) *" 795a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "min(0.5, shapeHalfSize.y);"); 796a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("rectCoverage = (%s != 0) ? 0.0 : maxCoverage;", 797a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kVertexAttrs)); 798a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 799a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.vsOut()) { 800a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut()); 801a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 802a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 803a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 804a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupOval(GrGLSLVertexBuilder* v) { 805a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Offset the inner and outer octagons by one pixel. Inner vs outer is indicated by coordAttrs. 806a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 ovalBloat = (%s != 0) ? bloat : -bloat;", 807a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kVertexAttrs)); 808a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("bloatedShapeCoords = %s * max(vec2(1.0 + ovalBloat), vec2(0));", 809a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords)); 810a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = bloatedShapeCoords * shapeHalfSize;", fEllipseCoords.vsOut()); 811a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fEllipseName.vsOut()) { 812a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 1.0 / (shapeHalfSize * shapeHalfSize);", fEllipseName.vsOut()); 813a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 814a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fBloatedRadius.vsOut()) { 815a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(fShapeIsCircle); 816a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = shapeHalfSize.x + 0.5;", fBloatedRadius.vsOut()); 817a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 818a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.vsOut()) { 819a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = int(%s != 0);", 820a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs)); 821a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 822a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fColorTimesRectCoverage.vsOut() || fRectCoverage.vsOut()) { 823a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("rectCoverage = 1.0;"); 824a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 825a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 826a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 827a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::adjustRRectVertices(GrGLSLVertexBuilder* v) { 828a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // We try to let the AA borders line up with the arc edges on their particular side, but we 829a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // can't allow them to get closer than one half pixel to the edge or they might overlap with 830a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // their neighboring border. 831a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("vec2 innerEdge = max(1.0 - bloat, vec2(0));"); 832a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 borderEdge = cornerSign * clamp(1.0 - radii, -innerEdge, innerEdge);"); 833a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // 0.5 is a special value that indicates this vertex is an arc edge. 834a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.x) == 0.5)" 835a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "bloatedShapeCoords.x = borderEdge.x;", fInputs.attr(Attrib::kShapeCoords)); 836a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.y) == 0.5)" 837a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "bloatedShapeCoords.y = borderEdge.y;", fInputs.attr(Attrib::kShapeCoords)); 838a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 839a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Adjust the interior border vertices to make the border one pixel wide. 0.75 is a special 840a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // value to indicate these points. 841a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.x) == 0.75) " 842a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "bloatedShapeCoords.x = cornerSign.x * innerEdge.x;", 843a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords)); 844a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.y) == 0.75) " 845a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "bloatedShapeCoords.y = cornerSign.y * innerEdge.y;", 846a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords)); 847a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 848a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 849a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onSetupRRect(GrGLSLVertexBuilder* v) { 850a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The geometry is laid out in such a way that rectCoverage will be 0 and 1 on the vertices, but 851a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // we still need to recompute this value because when the rrect gets thinner than one pixel, the 852a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // interior edge of the border will necessarily clamp, and we need to match the AA behavior of 853a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // the arc segments (i.e. distance from bloated edge only; ignoring the fact that the pixel 854a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // actully has less coverage because it's not completely inside the opposite edge.) 855a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("vec2 d = shapeHalfSize + 0.5 - abs(bloatedShapeCoords) * shapeHalfSize;"); 856a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("rectCoverage = min(d.x, d.y);"); 857a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 858a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!fShapeIsCircle); 859a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The AA border does not get closer than one half pixel to the edge of the rect, so to get a 860a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // smooth transition from flat edge to arc, we don't allow the radii to be smaller than one half 861a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // pixel. (We don't worry about the transition on the opposite side when a radius is so large 862a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // that the border clamped on that side.) 863a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 clampedRadii = max(radii, bloat);"); 864a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = (cornerSign * bloatedShapeCoords + clampedRadii - vec2(1)) * " 865a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "shapeHalfSize;", fEllipseCoords.vsOut()); 866a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 1.0 / (clampedRadii * clampedRadii * shapeHalfSize * shapeHalfSize);", 867a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fEllipseName.vsOut()); 868a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 869a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 870a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler, 871a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v) { 872a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("vec2 innerShapeHalfSize = shapeHalfSize / outer2Inner.xy;"); 873a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 87499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kOval_ShapeFlag == fOpInfo.fInnerShapeTypes) { 875a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("innerEllipseCoords", &fInnerEllipseCoords, 876a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kMedium_GrSLPrecision); 877dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addFlatVarying("innerEllipseName", &fInnerEllipseName, kHigh_GrSLPrecision); 878a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 879a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("distanceToInnerEdge", &fDistanceToInnerEdge, 880a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kMedium_GrSLPrecision); 881a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("innerShapeBloatedHalfSize", &fInnerShapeBloatedHalfSize, 882a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kMedium_GrSLPrecision); 88399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kRect_ShapeFlag != fOpInfo.fInnerShapeTypes) { 884dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords, 885dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton kMedium_GrSLPrecision); 886a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("innerEllipseName", &fInnerEllipseName, 887dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton kHigh_GrSLPrecision); 888dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kMedium_GrSLPrecision); 889a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 890a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 891a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 892a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 893a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupInnerRect(GrGLSLVertexBuilder* v) { 894a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerRRect.vsOut()) { 895a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The fragment shader will generalize every inner shape as a round rect. Since this one 896a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // is a rect, we simply emit bogus parameters for the round rect (effectively negative 897a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // radii) that ensure the fragment shader always takes the "emitRect" codepath. 898a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s.xy = abs(outer2Inner.xy) * (1.0 + bloat) + abs(outer2Inner.zw);", 899a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerRRect.vsOut()); 900a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 901a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 902a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 903a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::setupInnerOval(GrGLSLVertexBuilder* v) { 904a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 1.0 / (innerShapeHalfSize * innerShapeHalfSize);", 905a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerEllipseName.vsOut()); 906a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerEllipseCoords.vsOut()) { 907a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = innerShapeCoords * innerShapeHalfSize;", fInnerEllipseCoords.vsOut()); 908a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 909a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerRRect.vsOut()) { 910a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(0, 0, innerShapeHalfSize);", fInnerRRect.vsOut()); 911a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 912a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 913a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 9140caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) { 915a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The distance to ellipse formula doesn't work well when the radii are less than half a pixel. 916a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("innerRadii = max(innerRadii, bloat);"); 917a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 1.0 / (innerRadii * innerRadii * innerShapeHalfSize * " 918a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "innerShapeHalfSize);", 919a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerEllipseName.vsOut()); 920a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(1.0 - innerRadii, innerShapeHalfSize);", fInnerRRect.vsOut()); 921a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 922a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 923a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::onEmitCode(GrGLSLVertexBuilder* v, 924a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLPPFragmentBuilder* f, 925a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage, 926a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outColor) { 927a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fColorTimesRectCoverage.vsOut()) { 928a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!fRectCoverage.vsOut()); 929a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s * rectCoverage;", 930a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fColorTimesRectCoverage.vsOut(), fInputs.attr(Attrib::kColor)); 931a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 932a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fRectCoverage.vsOut()) { 933a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!fColorTimesRectCoverage.vsOut()); 934a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = rectCoverage;", fRectCoverage.vsOut()); 935a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 936a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 9376762dd6f73ec6a0bea0683175d1cf4568680bee4Ethan Nicholas SkString coverage("lowp float coverage"); 93899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (fOpInfo.fInnerShapeTypes || (!fTweakAlphaForCoverage && fTriangleIsArc.fsIn())) { 939a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s;", coverage.c_str()); 940a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton coverage = "coverage"; 941a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 942a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.fsIn()) { 943a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s == 0) {", fTriangleIsArc.fsIn()); 944a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, coverage.c_str(), outColor); 945a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 946a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fShapeIsCircle) { 947a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitCircle(f, coverage.c_str()); 948a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 94999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon bool ellipseCoordsMayBeNegative = SkToBool(fOpInfo.fShapeTypes & kOval_ShapeFlag); 950a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, fEllipseCoords.fsIn(), fEllipseName.fsIn(), 951a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton true /*ellipseCoordsNeedClamp*/, ellipseCoordsMayBeNegative, 952a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton coverage.c_str()); 953a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 954a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTweakAlphaForCoverage) { 955a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = %s * coverage;", outColor, fColor.fsIn()); 956a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 957a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 958a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 959a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, coverage.c_str(), outColor); 960a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 961a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 96299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (fOpInfo.fInnerShapeTypes) { 963a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("// Inner shape.\n"); 9646762dd6f73ec6a0bea0683175d1cf4568680bee4Ethan Nicholas SkString innerCoverageDecl("lowp float innerCoverage"); 96599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kOval_ShapeFlag == fOpInfo.fInnerShapeTypes) { 966a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, fInnerEllipseCoords.fsIn(), fInnerEllipseName.fsIn(), 967a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton true /*ellipseCoordsNeedClamp*/, true /*ellipseCoordsMayBeNegative*/, 968a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerCoverageDecl.c_str()); 969a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 970a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = innerShapeCoords * innerShapeHalfSize;", 971a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fDistanceToInnerEdge.vsOut()); 972a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = innerShapeHalfSize + 0.5;", fInnerShapeBloatedHalfSize.vsOut()); 973a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 97499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kRect_ShapeFlag == fOpInfo.fInnerShapeTypes) { 975a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitInnerRect(f, innerCoverageDecl.c_str()); 976a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 977a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = 0.0;", innerCoverageDecl.c_str()); 9781fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("mediump vec2 distanceToArcEdge = abs(%s) - %s.xy;", 979a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeCoords.fsIn(), fInnerRRect.fsIn()); 980a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("if (any(lessThan(distanceToArcEdge, vec2(1e-5)))) {"); 981a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitInnerRect(f, "innerCoverage"); 982a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 9831fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf( "mediump vec2 ellipseCoords = distanceToArcEdge * %s.zw;", 984a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerRRect.fsIn()); 985a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, "ellipseCoords", fInnerEllipseName.fsIn(), 986a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton false /*ellipseCoordsNeedClamp*/, 987a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton false /*ellipseCoordsMayBeNegative*/, "innerCoverage"); 988a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 989a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 990a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 991a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = vec4(max(coverage - innerCoverage, 0.0));", outCoverage); 992a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (!fTweakAlphaForCoverage) { 993a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = vec4(coverage);", outCoverage); 994a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 995a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 996a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 997a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitRect(GrGLSLPPFragmentBuilder* f, 998a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage, 999a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outColor) { 1000a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fColorTimesRectCoverage.fsIn()) { 1001a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = %s;", outColor, fColorTimesRectCoverage.fsIn()); 1002a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fTweakAlphaForCoverage) { 1003a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // We are drawing just ovals. The interior rect always has 100% coverage. 1004a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = %s;", outColor, fColor.fsIn()); 1005a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fRectCoverage.fsIn()) { 1006a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = %s;", outCoverage, fRectCoverage.fsIn()); 1007a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1008a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = 1.0;", outCoverage); 1009a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1010a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1011a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1012a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitCircle(GrGLSLPPFragmentBuilder* f, 1013a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage) { 1014a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // TODO: circleCoords = max(circleCoords, 0) if we decide to do this optimization on rrects. 101599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon SkASSERT(!(kRRect_ShapesMask & fOpInfo.fShapeTypes)); 10161fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("mediump float distanceToEdge = %s - length(%s);", 1017a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fBloatedRadius.fsIn(), fEllipseCoords.fsIn()); 1018a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = clamp(distanceToEdge, 0.0, 1.0);", outCoverage); 1019a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1020a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1021a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitArc(GrGLSLPPFragmentBuilder* f, 1022a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* ellipseCoords, 1023a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* ellipseName, 1024a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool ellipseCoordsNeedClamp, 1025a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool ellipseCoordsMayBeNegative, 1026a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage) { 1027a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!ellipseCoordsMayBeNegative || ellipseCoordsNeedClamp); 1028a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (ellipseCoordsNeedClamp) { 1029a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // This serves two purposes: 1030a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // - To restrict the arcs of rounded rects to their positive quadrants. 1031a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // - To avoid inversesqrt(0) in the ellipse formula. 1032a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (ellipseCoordsMayBeNegative) { 10331fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("mediump vec2 ellipseClampedCoords = max(abs(%s), vec2(1e-4));", 10341fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas ellipseCoords); 1035a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 10361fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("mediump vec2 ellipseClampedCoords = max(%s, vec2(1e-4));", 10371fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas ellipseCoords); 1038a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1039a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton ellipseCoords = "ellipseClampedCoords"; 1040a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1041a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // ellipseCoords are in pixel space and ellipseName is 1 / rx^2, 1 / ry^2. 10421fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("highp vec2 Z = %s * %s;", ellipseCoords, ellipseName); 1043a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1. 10441fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("highp float implicit = dot(Z, %s) - 1.0;", ellipseCoords); 1045a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // gradDot is the squared length of the gradient of the implicit. 10461fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("highp float gradDot = 4.0 * dot(Z, Z);"); 10471fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppend ("mediump float approxDist = implicit * inversesqrt(gradDot);"); 1048a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = clamp(0.5 - approxDist, 0.0, 1.0);", outCoverage); 1049a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1050a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1051a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendCoverage::emitInnerRect(GrGLSLPPFragmentBuilder* f, 1052a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* outCoverage) { 10531fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("lowp vec2 c = %s - abs(%s);", 1054a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeBloatedHalfSize.fsIn(), fDistanceToInnerEdge.fsIn()); 1055a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("%s = clamp(min(c.x, c.y), 0.0, 1.0);", outCoverage); 1056a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1057a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1058a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton//////////////////////////////////////////////////////////////////////////////////////////////////// 1059a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1060a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonclass GLSLInstanceProcessor::BackendMultisample : public Backend { 1061a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonpublic: 106299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon BackendMultisample(OpInfo opInfo, const VertexInputs& inputs, int effectiveSampleCnt) 106399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon : INHERITED(opInfo, inputs) 106499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fEffectiveSampleCnt(effectiveSampleCnt) 106599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fShapeCoords(kVec2f_GrSLType) 106699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fShapeInverseMatrix(kMat22f_GrSLType) 106799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fFragShapeHalfSpan(kVec2f_GrSLType) 106899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fArcTest(kVec2f_GrSLType) 106999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fArcInverseMatrix(kMat22f_GrSLType) 107099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fFragArcHalfSpan(kVec2f_GrSLType) 107199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fEarlyAccept(kInt_GrSLType) 107299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fInnerShapeInverseMatrix(kMat22f_GrSLType) 107399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon , fFragInnerShapeHalfSpan(kVec2f_GrSLType) { 107499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon fRectTrianglesMaySplit = fOpInfo.fHasPerspective; 107599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon fNeedsNeighborRadii = this->isMixedSampled() && !fOpInfo.fHasPerspective; 1076a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1077a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1078a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonprivate: 1079af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon bool isMixedSampled() const { return GrAAType::kMixedSamples == fOpInfo.aaType(); } 1080a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1081a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onInit(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override; 1082a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupRect(GrGLSLVertexBuilder*) override; 1083a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupOval(GrGLSLVertexBuilder*) override; 1084a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void adjustRRectVertices(GrGLSLVertexBuilder*) override; 1085a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onSetupRRect(GrGLSLVertexBuilder*) override; 1086a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1087a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override; 1088a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupInnerRect(GrGLSLVertexBuilder*) override; 1089a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void setupInnerOval(GrGLSLVertexBuilder*) override; 10900caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdalton void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override; 1091a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1092a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char*, 1093a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char*) override; 1094a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1095a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton struct EmitShapeCoords { 1096a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const GrGLSLVarying* fVarying; 1097a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* fInverseMatrix; 1098a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* fFragHalfSpan; 1099a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton }; 1100a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1101a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton struct EmitShapeOpts { 1102a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fIsTightGeometry; 1103a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fResolveMixedSamples; 1104a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fInvertCoverage; 1105a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton }; 1106a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1107a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitRect(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, const EmitShapeOpts&); 1108a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitArc(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, bool coordsMayBeNegative, 1109a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool clampCoords, const EmitShapeOpts&); 1110a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void emitSimpleRRect(GrGLSLPPFragmentBuilder*, const EmitShapeCoords&, const char* rrect, 1111a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeOpts&); 1112a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void interpolateAtSample(GrGLSLPPFragmentBuilder*, const GrGLSLVarying&, const char* sampleIdx, 1113a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* interpolationMatrix); 1114a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void acceptOrRejectWholeFragment(GrGLSLPPFragmentBuilder*, bool inside, const EmitShapeOpts&); 1115a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton void acceptCoverageMask(GrGLSLPPFragmentBuilder*, const char* shapeMask, const EmitShapeOpts&, 1116a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool maybeSharedEdge = true); 1117a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1118a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton int fEffectiveSampleCnt; 1119a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool fRectTrianglesMaySplit; 1120a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fShapeCoords; 1121a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fShapeInverseMatrix; 1122a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fFragShapeHalfSpan; 1123a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fArcTest; 1124a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fArcInverseMatrix; 1125a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fFragArcHalfSpan; 1126a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fEarlyAccept; 1127a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fInnerShapeInverseMatrix; 1128a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertToFrag fFragInnerShapeHalfSpan; 1129a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkString fSquareFun; 1130a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1131a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton typedef Backend INHERITED; 1132a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 1133a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1134a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onInit(GrGLSLVaryingHandler* varyingHandler, 1135a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v) { 1136a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!this->isMixedSampled()) { 113799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kRect_ShapeFlag != fOpInfo.fShapeTypes) { 1138dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, kLow_GrSLPrecision); 1139a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("arcCoords", &fArcCoords, kHigh_GrSLPrecision); 114099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!fOpInfo.fHasPerspective) { 1141a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("arcInverseMatrix", &fArcInverseMatrix, 1142a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1143a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("fragArcHalfSpan", &fFragArcHalfSpan, 1144a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1145a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 114699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon } else if (!fOpInfo.fInnerShapeTypes) { 1147a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return; 1148a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1149a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1150a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("shapeCoords", &fShapeCoords, kHigh_GrSLPrecision); 115199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!fOpInfo.fHasPerspective) { 1152a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("shapeInverseMatrix", &fShapeInverseMatrix, 1153a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1154a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("fragShapeHalfSpan", &fFragShapeHalfSpan, 1155a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1156a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 115799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (fOpInfo.fShapeTypes & kRRect_ShapesMask) { 1158a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("arcCoords", &fArcCoords, kHigh_GrSLPrecision); 1159a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("arcTest", &fArcTest, kHigh_GrSLPrecision); 116099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!fOpInfo.fHasPerspective) { 1161a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("arcInverseMatrix", &fArcInverseMatrix, 1162a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1163a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("fragArcHalfSpan", &fFragArcHalfSpan, 1164a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1165a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 116699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon } else if (fOpInfo.fShapeTypes & kOval_ShapeFlag) { 1167a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcCoords = fShapeCoords; 1168a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcInverseMatrix = fShapeInverseMatrix; 1169a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fFragArcHalfSpan = fFragShapeHalfSpan; 117099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (fOpInfo.fShapeTypes & kRect_ShapeFlag) { 1171a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("triangleIsArc", &fTriangleIsArc, 1172dd57dd796845da6ec2e1f44dc1e0b7821c1e4db1csmartdalton kLow_GrSLPrecision); 1173a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1174a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 117599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kRect_ShapeFlag != fOpInfo.fShapeTypes) { 117699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon v->defineConstantf("int", "SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1); 117799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon varyingHandler->addFlatVarying("earlyAccept", &fEarlyAccept, kHigh_GrSLPrecision); 1178a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1179a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 118099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!fOpInfo.fHasPerspective) { 1181a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("mat2 shapeInverseMatrix = inverse(mat2(shapeMatrix));"); 1182a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend("vec2 fragShapeSpan = abs(vec4(shapeInverseMatrix).xz) + " 1183a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "abs(vec4(shapeInverseMatrix).yw);"); 1184a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1185a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1186a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1187a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupRect(GrGLSLVertexBuilder* v) { 1188a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fShapeCoords.vsOut()) { 1189a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s;", fShapeCoords.vsOut(), this->outShapeCoords()); 1190a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1191a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fShapeInverseMatrix.vsOut()) { 1192a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = shapeInverseMatrix;", fShapeInverseMatrix.vsOut()); 1193a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1194a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fFragShapeHalfSpan.vsOut()) { 1195a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragShapeHalfSpan.vsOut()); 1196a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1197a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fArcTest.vsOut()) { 1198a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Pick a value that is not > 0. 1199a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec2(0);", fArcTest.vsOut()); 1200a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1201a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.vsOut()) { 1202a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0;", fTriangleIsArc.vsOut()); 1203a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1204a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fEarlyAccept.vsOut()) { 1205a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = SAMPLE_MASK_ALL;", fEarlyAccept.vsOut()); 1206a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1207a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1208a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1209a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupOval(GrGLSLVertexBuilder* v) { 1210a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = abs(%s);", fArcCoords.vsOut(), this->outShapeCoords()); 1211a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fArcInverseMatrix.vsOut()) { 1212a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("vec2 s = sign(%s);", this->outShapeCoords()); 1213a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = shapeInverseMatrix * mat2(s.x, 0, 0 , s.y);", 1214a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcInverseMatrix.vsOut()); 1215a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1216a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fFragArcHalfSpan.vsOut()) { 1217a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragArcHalfSpan.vsOut()); 1218a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1219a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fArcTest.vsOut()) { 1220a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Pick a value that is > 0. 1221a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec2(1);", fArcTest.vsOut()); 1222a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1223a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.vsOut()) { 1224a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!this->isMixedSampled()) { 1225a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s & 1;", 1226a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fTriangleIsArc.vsOut(), fInputs.attr(Attrib::kVertexAttrs)); 1227a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1228a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 1;", fTriangleIsArc.vsOut()); 1229a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1230a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1231a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fEarlyAccept.vsOut()) { 1232a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = ~%s & SAMPLE_MASK_ALL;", 1233a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fEarlyAccept.vsOut(), fInputs.attr(Attrib::kVertexAttrs)); 1234a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1235a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1236a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1237a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::adjustRRectVertices(GrGLSLVertexBuilder* v) { 1238a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!this->isMixedSampled()) { 1239a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton INHERITED::adjustRRectVertices(v); 1240a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return; 1241a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1242a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 124399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!fOpInfo.fHasPerspective) { 1244a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // For the mixed samples algorithm it's best to bloat the corner triangles a bit so that 1245a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // more of the pixels that cross into the arc region are completely inside the shared edges. 1246a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // We also snap to a regular rect if the radii shrink smaller than a pixel. 1247a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 midpt = 0.5 * (neighborRadii - radii);"); 1248a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 cornerSize = any(lessThan(radii, fragShapeSpan)) ? " 1249a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "vec2(0) : min(radii + 0.5 * fragShapeSpan, 1.0 - midpt);"); 1250a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1251a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // TODO: We could still bloat the corner triangle in the perspective case; we would just 1252a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // need to find the screen-space derivative of shape coords at this particular point. 1253a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 cornerSize = any(lessThan(radii, vec2(1e-3))) ? vec2(0) : radii;"); 1254a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1255a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1256a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.x) == 0.5)" 1257a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "%s.x = cornerSign.x * (1.0 - cornerSize.x);", 1258a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords); 1259a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("if (abs(%s.y) == 0.5)" 1260a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "%s.y = cornerSign.y * (1.0 - cornerSize.y);", 1261a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInputs.attr(Attrib::kShapeCoords), fModifiedShapeCoords); 1262a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1263a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1264a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onSetupRRect(GrGLSLVertexBuilder* v) { 1265a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fShapeCoords.vsOut()) { 1266a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = %s;", fShapeCoords.vsOut(), this->outShapeCoords()); 1267a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1268a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fShapeInverseMatrix.vsOut()) { 1269a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = shapeInverseMatrix;", fShapeInverseMatrix.vsOut()); 1270a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1271a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fFragShapeHalfSpan.vsOut()) { 1272a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0.5 * fragShapeSpan;", fFragShapeHalfSpan.vsOut()); 1273a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1274a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fArcInverseMatrix.vsOut()) { 1275a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("vec2 s = cornerSign / radii;"); 1276a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = shapeInverseMatrix * mat2(s.x, 0, 0, s.y);", 1277a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcInverseMatrix.vsOut()); 1278a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1279a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fFragArcHalfSpan.vsOut()) { 1280a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0.5 * (abs(vec4(%s).xz) + abs(vec4(%s).yw));", 1281a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fFragArcHalfSpan.vsOut(), fArcInverseMatrix.vsOut(), 1282a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcInverseMatrix.vsOut()); 1283a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1284a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fArcTest.vsOut()) { 1285a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The interior triangles are laid out as a fan. fArcTest is both distances from shared 1286a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // edges of a fan triangle to a point within that triangle. fArcTest is used to check if a 1287a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // fragment is too close to either shared edge, in which case we point sample the shape as a 1288a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // rect at that point in order to guarantee the mixed samples discard logic works correctly. 1289a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = (cornerSize == vec2(0)) ? vec2(0) : " 1290a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "cornerSign * %s * mat2(1, cornerSize.x - 1.0, cornerSize.y - 1.0, 1);", 1291a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcTest.vsOut(), fModifiedShapeCoords); 129299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!fOpInfo.fHasPerspective) { 1293a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Shift the point at which distances to edges are measured from the center of the pixel 1294a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // to the corner. This way the sign of fArcTest will quickly tell us whether a pixel 1295a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // is completely inside the shared edge. Perspective mode will accomplish this same task 1296a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // by finding the derivatives in the fragment shader. 1297a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s -= 0.5 * (fragShapeSpan.yx * abs(radii - 1.0) + fragShapeSpan);", 1298a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcTest.vsOut()); 1299a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1300a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1301a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fEarlyAccept.vsOut()) { 1302a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(this->isMixedSampled()); 1303a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = all(equal(vec2(1), abs(%s))) ? 0 : SAMPLE_MASK_ALL;", 1304a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fEarlyAccept.vsOut(), fInputs.attr(Attrib::kShapeCoords)); 1305a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1306a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1307a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1308a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid 1309a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGLSLInstanceProcessor::BackendMultisample::onInitInnerShape(GrGLSLVaryingHandler* varyingHandler, 1310a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLVertexBuilder* v) { 1311a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addVarying("innerShapeCoords", &fInnerShapeCoords, kHigh_GrSLPrecision); 131299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kOval_ShapeFlag != fOpInfo.fInnerShapeTypes && 131399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon kRect_ShapeFlag != fOpInfo.fInnerShapeTypes) { 1314a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("innerRRect", &fInnerRRect, kHigh_GrSLPrecision); 1315a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 131699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!fOpInfo.fHasPerspective) { 1317a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("innerShapeInverseMatrix", &fInnerShapeInverseMatrix, 1318a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1319a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = shapeInverseMatrix * mat2(outer2Inner.x, 0, 0, outer2Inner.y);", 1320a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeInverseMatrix.vsOut()); 1321a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton varyingHandler->addFlatVarying("fragInnerShapeHalfSpan", &fFragInnerShapeHalfSpan, 1322a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kHigh_GrSLPrecision); 1323a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = 0.5 * fragShapeSpan * outer2Inner.xy;", 1324a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fFragInnerShapeHalfSpan.vsOut()); 1325a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1326a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1327a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1328a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupInnerRect(GrGLSLVertexBuilder* v) { 1329a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerRRect.vsOut()) { 1330a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The fragment shader will generalize every inner shape as a round rect. Since this one 1331a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // is a rect, we simply emit bogus parameters for the round rect (negative radii) that 1332a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // ensure the fragment shader always takes the "sample as rect" codepath. 1333a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(2.0 * (inner.zw - inner.xy) / (outer.zw - outer.xy), vec2(0));", 1334a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerRRect.vsOut()); 1335a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1336a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1337a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1338a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::setupInnerOval(GrGLSLVertexBuilder* v) { 1339a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fInnerRRect.vsOut()) { 1340a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(0, 0, 1, 1);", fInnerRRect.vsOut()); 1341a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1342a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1343a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 13440caee1778d92c30ff6eb053f7fb58509d275a2dfcsmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) { 1345a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Avoid numeric instability by not allowing the inner radii to get smaller than 1/10th pixel. 1346a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fFragInnerShapeHalfSpan.vsOut()) { 1347a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("innerRadii = max(innerRadii, 2e-1 * %s);", fFragInnerShapeHalfSpan.vsOut()); 1348a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1349a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppend ("innerRadii = max(innerRadii, vec2(1e-4));"); 1350a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1351a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton v->codeAppendf("%s = vec4(1.0 - innerRadii, 1.0 / innerRadii);", fInnerRRect.vsOut()); 1352a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1353a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1354a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::onEmitCode(GrGLSLVertexBuilder*, 1355a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrGLSLPPFragmentBuilder* f, 1356a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char*, const char*) { 13575961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas f->defineConstant("SAMPLE_COUNT", fEffectiveSampleCnt); 1358a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (this->isMixedSampled()) { 13595961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas f->defineConstantf("int", "SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1); 13605961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas f->defineConstantf("int", "SAMPLE_MASK_MSB", "0x%x", 1 << (fEffectiveSampleCnt - 1)); 1361a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1362a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 136399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kRect_ShapeFlag != (fOpInfo.fShapeTypes | fOpInfo.fInnerShapeTypes)) { 136499938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon GrShaderVar x("x", kVec2f_GrSLType, GrShaderVar::kNonArray, kHigh_GrSLPrecision); 1365a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->emitFunction(kFloat_GrSLType, "square", 1, &x, "return dot(x, x);", &fSquareFun); 1366a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1367a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1368a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton EmitShapeCoords shapeCoords; 1369a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton shapeCoords.fVarying = &fShapeCoords; 1370a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton shapeCoords.fInverseMatrix = fShapeInverseMatrix.fsIn(); 1371a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton shapeCoords.fFragHalfSpan = fFragShapeHalfSpan.fsIn(); 1372a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1373a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton EmitShapeCoords arcCoords; 1374a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton arcCoords.fVarying = &fArcCoords; 1375a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton arcCoords.fInverseMatrix = fArcInverseMatrix.fsIn(); 1376a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton arcCoords.fFragHalfSpan = fFragArcHalfSpan.fsIn(); 137799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon bool clampArcCoords = this->isMixedSampled() && (fOpInfo.fShapeTypes & kRRect_ShapesMask); 1378a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1379a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton EmitShapeOpts opts; 1380a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton opts.fIsTightGeometry = true; 1381a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton opts.fResolveMixedSamples = this->isMixedSampled(); 1382a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton opts.fInvertCoverage = false; 1383a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 138499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (fOpInfo.fHasPerspective && fOpInfo.fInnerShapeTypes) { 1385a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // This determines if the fragment should consider the inner shape in its sample mask. 1386a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // We take the derivative early in case discards may occur before we get to the inner shape. 13871fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("highp vec2 fragInnerShapeApproxHalfSpan = 0.5 * fwidth(%s);", 1388a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fInnerShapeCoords.fsIn()); 1389a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1390a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1391a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (!this->isMixedSampled()) { 1392a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!fArcTest.fsIn()); 1393a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (fTriangleIsArc.fsIn()) { 1394a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s != 0) {", fTriangleIsArc.fsIn()); 1395a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, arcCoords, false, clampArcCoords, opts); 1396a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1397a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1398a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1399a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1400a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* arcTest = fArcTest.fsIn(); 140199ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (arcTest && fOpInfo.fHasPerspective) { 1402e0d362929d6569e8737d80dead791c640390e819csmartdalton // The non-perspective version accounts for fwidth() in the vertex shader. 1403a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // We make sure to take the derivative here, before a neighbor pixel may early accept. 14041fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("highp vec2 arcTest = %s - 0.5 * fwidth(%s);", 1405a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fArcTest.fsIn(), fArcTest.fsIn()); 1406a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton arcTest = "arcTest"; 1407a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1408a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* earlyAccept = fEarlyAccept.fsIn() ? fEarlyAccept.fsIn() : "SAMPLE_MASK_ALL"; 1409a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (gl_SampleMaskIn[0] == %s) {", earlyAccept); 1410a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage(earlyAccept); 1411a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 1412a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (arcTest) { 1413a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // At this point, if the sample mask is all set it means we are inside an arc triangle. 1414a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (gl_SampleMaskIn[0] == SAMPLE_MASK_ALL || " 1415a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton "all(greaterThan(%s, vec2(0)))) {", arcTest); 1416a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, arcCoords, false, clampArcCoords, opts); 1417a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 1418a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, shapeCoords, opts); 1419a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1420a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (fTriangleIsArc.fsIn()) { 1421a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s == 0) {", fTriangleIsArc.fsIn()); 1422a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, shapeCoords, opts); 1423a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 1424a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, arcCoords, false, clampArcCoords, opts); 1425a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 142699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon } else if (fOpInfo.fShapeTypes == kOval_ShapeFlag) { 1427a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, arcCoords, false, clampArcCoords, opts); 1428a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 142999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon SkASSERT(fOpInfo.fShapeTypes == kRect_ShapeFlag); 1430a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, shapeCoords, opts); 1431a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1432a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1433a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1434a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 143599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (fOpInfo.fInnerShapeTypes) { 1436a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("// Inner shape.\n"); 1437a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1438a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton EmitShapeCoords innerShapeCoords; 1439a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerShapeCoords.fVarying = &fInnerShapeCoords; 144099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!fOpInfo.fHasPerspective) { 1441a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerShapeCoords.fInverseMatrix = fInnerShapeInverseMatrix.fsIn(); 1442a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerShapeCoords.fFragHalfSpan = fFragInnerShapeHalfSpan.fsIn(); 1443a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1444a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1445a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton EmitShapeOpts innerOpts; 1446a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerOpts.fIsTightGeometry = false; 1447a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerOpts.fResolveMixedSamples = false; // Mixed samples are resolved in the outer shape. 1448a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton innerOpts.fInvertCoverage = true; 1449a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 145099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kOval_ShapeFlag == fOpInfo.fInnerShapeTypes) { 1451a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitArc(f, innerShapeCoords, true, false, innerOpts); 1452a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1453a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (all(lessThan(abs(%s), 1.0 + %s))) {", fInnerShapeCoords.fsIn(), 145499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon !fOpInfo.fHasPerspective ? innerShapeCoords.fFragHalfSpan 145599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon : "fragInnerShapeApproxHalfSpan"); // Above. 145699ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (kRect_ShapeFlag == fOpInfo.fInnerShapeTypes) { 1457a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, innerShapeCoords, innerOpts); 1458a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1459a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitSimpleRRect(f, innerShapeCoords, fInnerRRect.fsIn(), innerOpts); 1460a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1461a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1462a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1463a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1464a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1465a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1466a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::emitRect(GrGLSLPPFragmentBuilder* f, 1467a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeCoords& coords, 1468a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeOpts& opts) { 1469a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Full MSAA doesn't need to do anything to draw a rect. 1470a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!opts.fIsTightGeometry || opts.fResolveMixedSamples); 1471a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (coords.fFragHalfSpan) { 1472a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (all(lessThanEqual(abs(%s), 1.0 - %s))) {", 1473a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton coords.fVarying->fsIn(), coords.fFragHalfSpan); 1474a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The entire pixel is inside the rect. 1475a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptOrRejectWholeFragment(f, true, opts); 1476a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else "); 1477a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (opts.fIsTightGeometry && !fRectTrianglesMaySplit) { 1478a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (any(lessThan(abs(%s), 1.0 - %s))) {", 1479a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton coords.fVarying->fsIn(), coords.fFragHalfSpan); 1480a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The pixel falls on an edge of the rectangle and is known to not be on a shared edge. 1481a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptCoverageMask(f, "gl_SampleMaskIn[0]", opts, false); 1482a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else"); 1483a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1484a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("{"); 1485a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1486a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("int rectMask = 0;"); 1487a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("for (int i = 0; i < SAMPLE_COUNT; i++) {"); 14881fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppend ( "highp vec2 pt = "); 1489a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->interpolateAtSample(f, *coords.fVarying, "i", coords.fInverseMatrix); 1490a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( ";"); 1491a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "if (all(lessThan(abs(pt), vec2(1)))) rectMask |= (1 << i);"); 1492a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1493a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptCoverageMask(f, "rectMask", opts); 1494a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (coords.fFragHalfSpan) { 1495a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1496a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1497a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1498a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1499a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::emitArc(GrGLSLPPFragmentBuilder* f, 1500a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeCoords& coords, 1501a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool coordsMayBeNegative, bool clampCoords, 1502a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeOpts& opts) { 1503a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (coords.fFragHalfSpan) { 1504a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkString absArcCoords; 1505a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton absArcCoords.printf(coordsMayBeNegative ? "abs(%s)" : "%s", coords.fVarying->fsIn()); 1506a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (clampCoords) { 1507a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s(max(%s + %s, vec2(0))) < 1.0) {", 1508a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan); 1509a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1510a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s(%s + %s) < 1.0) {", 1511a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan); 1512a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1513a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The entire pixel is inside the arc. 1514a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptOrRejectWholeFragment(f, true, opts); 1515a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("} else if (%s(max(%s - %s, vec2(0))) >= 1.0) {", 1516a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fSquareFun.c_str(), absArcCoords.c_str(), coords.fFragHalfSpan); 1517a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The entire pixel is outside the arc. 1518a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptOrRejectWholeFragment(f, false, opts); 1519a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 1520a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1521a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "int arcMask = 0;"); 1522a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "for (int i = 0; i < SAMPLE_COUNT; i++) {"); 15231fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppend ( "highp vec2 pt = "); 1524a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->interpolateAtSample(f, *coords.fVarying, "i", coords.fInverseMatrix); 1525a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( ";"); 1526a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (clampCoords) { 1527a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!coordsMayBeNegative); 1528a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "pt = max(pt, vec2(0));"); 1529a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1530a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "if (%s(pt) < 1.0) arcMask |= (1 << i);", fSquareFun.c_str()); 1531a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "}"); 1532a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptCoverageMask(f, "arcMask", opts); 1533a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (coords.fFragHalfSpan) { 1534a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1535a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1536a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1537a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1538a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::emitSimpleRRect(GrGLSLPPFragmentBuilder* f, 1539a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeCoords& coords, 1540a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* rrect, 1541a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeOpts& opts) { 15421fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("highp vec2 distanceToArcEdge = abs(%s) - %s.xy;", coords.fVarying->fsIn(), 15431fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas rrect); 1544a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("if (any(lessThan(distanceToArcEdge, vec2(0)))) {"); 1545a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->emitRect(f, coords, opts); 1546a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 1547a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (coords.fInverseMatrix && coords.fFragHalfSpan) { 15481fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("highp vec2 rrectCoords = distanceToArcEdge * %s.zw;", rrect); 15491fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf("highp vec2 fragRRectHalfSpan = %s * %s.zw;", coords.fFragHalfSpan, rrect); 1550a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if (%s(rrectCoords + fragRRectHalfSpan) <= 1.0) {", fSquareFun.c_str()); 1551a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The entire pixel is inside the round rect. 1552a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptOrRejectWholeFragment(f, true, opts); 1553a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("} else if (%s(max(rrectCoords - fragRRectHalfSpan, vec2(0))) >= 1.0) {", 1554a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fSquareFun.c_str()); 1555a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The entire pixel is outside the round rect. 1556a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptOrRejectWholeFragment(f, false, opts); 1557a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 15581fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf( "highp vec2 s = %s.zw * sign(%s);", rrect, coords.fVarying->fsIn()); 15591fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf( "highp mat2 innerRRectInverseMatrix = %s * mat2(s.x, 0, 0, s.y);", 1560a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton coords.fInverseMatrix); 15611fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppend ( "highp int rrectMask = 0;"); 1562a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "for (int i = 0; i < SAMPLE_COUNT; i++) {"); 15631fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppend ( "highp vec2 pt = rrectCoords + "); 1564a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendOffsetToSample("i", GrGLSLFPFragmentBuilder::kSkiaDevice_Coordinates); 1565a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "* innerRRectInverseMatrix;"); 1566a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "if (%s(max(pt, vec2(0))) < 1.0) rrectMask |= (1 << i);", 1567a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton fSquareFun.c_str()); 1568a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( "}"); 1569a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptCoverageMask(f, "rrectMask", opts); 1570a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1571a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1572a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("int rrectMask = 0;"); 1573a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("for (int i = 0; i < SAMPLE_COUNT; i++) {"); 15741fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppend ( "highp vec2 shapePt = "); 1575a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->interpolateAtSample(f, *coords.fVarying, "i", nullptr); 1576a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ( ";"); 15771fc83b131afa7c29e971dd3ccc7906006bde6c09Ethan Nicholas f->codeAppendf( "highp vec2 rrectPt = max(abs(shapePt) - %s.xy, vec2(0)) * %s.zw;", 1578a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton rrect, rrect); 1579a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf( "if (%s(rrectPt) < 1.0) rrectMask |= (1 << i);", fSquareFun.c_str()); 1580a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1581a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton this->acceptCoverageMask(f, "rrectMask", opts); 1582a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1583a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1584a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1585a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1586a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::interpolateAtSample(GrGLSLPPFragmentBuilder* f, 1587a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const GrGLSLVarying& varying, 1588a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* sampleIdx, 1589a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* interpolationMatrix) { 1590a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (interpolationMatrix) { 1591a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("(%s + ", varying.fsIn()); 1592a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendOffsetToSample(sampleIdx, GrGLSLFPFragmentBuilder::kSkiaDevice_Coordinates); 1593a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf(" * %s)", interpolationMatrix); 1594a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1595a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkAssertResult( 1596a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->enableFeature(GrGLSLFragmentBuilder::kMultisampleInterpolation_GLSLFeature)); 1597a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("interpolateAtOffset(%s, ", varying.fsIn()); 1598a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->appendOffsetToSample(sampleIdx, GrGLSLFPFragmentBuilder::kGLSLWindow_Coordinates); 1599a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend(")"); 1600a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1601a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1602a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1603a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid 1604a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGLSLInstanceProcessor::BackendMultisample::acceptOrRejectWholeFragment(GrGLSLPPFragmentBuilder* f, 1605a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool inside, 1606a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeOpts& opts) { 1607a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (inside != opts.fInvertCoverage) { // Accept the entire fragment. 1608a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (opts.fResolveMixedSamples) { 1609a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // This is a mixed sampled fragment in the interior of the shape. Reassign 100% coverage 1610a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // to one fragment, and drop all other fragments that may fall on this same pixel. Since 1611a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // our geometry is water tight and non-overlapping, we can take advantage of the 1612a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // properties that (1) the incoming sample masks will be disjoint across fragments that 1613a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // fall on a common pixel, and (2) since the entire fragment is inside the shape, each 1614a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // sample's corresponding bit will be set in the incoming sample mask of exactly one 1615a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // fragment. 1616a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend("if ((gl_SampleMaskIn[0] & SAMPLE_MASK_MSB) == 0) {"); 1617a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Drop this fragment. 161899ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!fOpInfo.fCannotDiscard) { 1619a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend("discard;"); 1620a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1621a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage("0"); 1622a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1623a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend("} else {"); 1624a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Override the lone surviving fragment to full coverage. 1625a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage("-1"); 1626a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend("}"); 1627a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1628a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { // Reject the entire fragment. 162999ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!fOpInfo.fCannotDiscard) { 1630a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend("discard;"); 1631a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else if (opts.fResolveMixedSamples) { 1632a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage("0"); 1633a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1634a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->maskSampleCoverage("0"); 1635a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1636a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1637a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1638a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1639a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonvoid GLSLInstanceProcessor::BackendMultisample::acceptCoverageMask(GrGLSLPPFragmentBuilder* f, 1640a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const char* shapeMask, 1641a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const EmitShapeOpts& opts, 1642a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton bool maybeSharedEdge) { 1643a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (opts.fResolveMixedSamples) { 1644a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (maybeSharedEdge) { 1645a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // This is a mixed sampled fragment, potentially on the outer edge of the shape, with 1646a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // only partial shape coverage. Override the coverage of one fragment to "shapeMask", 1647a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // and drop all other fragments that may fall on this same pixel. Since our geometry is 1648a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // water tight, non-overlapping, and completely contains the shape, this means that each 1649a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // "on" bit from shapeMask is guaranteed to be set in the incoming sample mask of one, 1650a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // and only one, fragment that falls on this same pixel. 1651a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkASSERT(!opts.fInvertCoverage); 1652a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppendf("if ((gl_SampleMaskIn[0] & (1 << findMSB(%s))) == 0) {", shapeMask); 1653a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Drop this fragment. 165499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon if (!fOpInfo.fCannotDiscard) { 1655a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("discard;"); 1656a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1657a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage("0"); 1658a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1659a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("} else {"); 1660a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Override the coverage of the lone surviving fragment to "shapeMask". 1661a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage(shapeMask); 1662a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->codeAppend ("}"); 1663a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1664a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->overrideSampleCoverage(shapeMask); 1665a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1666a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } else { 1667a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton f->maskSampleCoverage(shapeMask, opts.fInvertCoverage); 1668a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1669a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1670a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1671a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton//////////////////////////////////////////////////////////////////////////////////////////////////// 1672a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 167399ad164886ba39f688ebabecd5fe20dd5d923ba0Brian SalomonGLSLInstanceProcessor::Backend* GLSLInstanceProcessor::Backend::Create(const GrPipeline& pipeline, 167499ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon OpInfo opInfo, 167599ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon const VertexInputs& inputs) { 1676af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon switch (opInfo.aaType()) { 1677a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton default: 1678a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton SkFAIL("Unexpected antialias mode."); 1679af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kNone: 168099ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon return new BackendNonAA(opInfo, inputs); 1681af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kCoverage: 168299ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon return new BackendCoverage(opInfo, inputs); 1683af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kMSAA: 1684af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kMixedSamples: { 1685a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton const GrRenderTargetPriv& rtp = pipeline.getRenderTarget()->renderTargetPriv(); 1686c633abbb342e3af0e56382e8cb7e7d9fed71e237csmartdalton const GrGpu::MultisampleSpecs& specs = rtp.getMultisampleSpecs(pipeline); 168799ad164886ba39f688ebabecd5fe20dd5d923ba0Brian Salomon return new BackendMultisample(opInfo, inputs, specs.fEffectiveSampleCnt); 1688a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1689a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 1690a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 1691a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1692a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton//////////////////////////////////////////////////////////////////////////////////////////////////// 1693a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1694a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst ShapeVertex kVertexData[] = { 1695a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Rectangle. 1696a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1, +1, ~0}, /*0*/ 1697a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1, +1, ~0}, /*1*/ 1698a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1, -1, ~0}, /*2*/ 1699a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1, -1, ~0}, /*3*/ 1700a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The next 4 are for the bordered version. 1701a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1, +1, 0}, /*4*/ 1702a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1, +1, 0}, /*5*/ 1703a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1, -1, 0}, /*6*/ 1704a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1, -1, 0}, /*7*/ 1705a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1706a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Octagon that inscribes the unit circle, cut by an interior unit octagon. 1707a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.000000f, 0.000000f, 0}, /* 8*/ 1708a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.000000f, +0.414214f, ~0}, /* 9*/ 1709a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.707106f, +0.707106f, 0}, /*10*/ 1710a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.414214f, +1.000000f, ~0}, /*11*/ 1711a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.000000f, +1.000000f, 0}, /*12*/ 1712a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.414214f, +1.000000f, ~0}, /*13*/ 1713a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.707106f, +0.707106f, 0}, /*14*/ 1714a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.000000f, +0.414214f, ~0}, /*15*/ 1715a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.000000f, 0.000000f, 0}, /*16*/ 1716a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.000000f, -0.414214f, ~0}, /*17*/ 1717a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.707106f, -0.707106f, 0}, /*18*/ 1718a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.414214f, -1.000000f, ~0}, /*19*/ 1719a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.000000f, -1.000000f, 0}, /*20*/ 1720a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.414214f, -1.000000f, ~0}, /*21*/ 1721a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.707106f, -0.707106f, 0}, /*22*/ 1722a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.000000f, -0.414214f, ~0}, /*23*/ 1723a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // This vertex is for the fanned versions. 1724a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.000000f, 0.000000f, ~0}, /*24*/ 1725a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1726a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Rectangle with disjoint corner segments. 1727a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.0, +0.5, 0x3}, /*25*/ 1728a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.0, +1.0, 0x3}, /*26*/ 1729a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.5, +1.0, 0x3}, /*27*/ 1730a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.5, +1.0, 0x2}, /*28*/ 1731a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.0, +1.0, 0x2}, /*29*/ 1732a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.0, +0.5, 0x2}, /*30*/ 1733a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.0, -0.5, 0x0}, /*31*/ 1734a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.0, -1.0, 0x0}, /*32*/ 1735a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.5, -1.0, 0x0}, /*33*/ 1736a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.5, -1.0, 0x1}, /*34*/ 1737a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.0, -1.0, 0x1}, /*35*/ 1738a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.0, -0.5, 0x1}, /*36*/ 1739a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The next 4 are for the fanned version. 1740a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.0, 0.0, 0x3}, /*37*/ 1741a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.0, 0.0, 0x2}, /*38*/ 1742a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.0, 0.0, 0x0}, /*39*/ 1743a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton { 0.0, 0.0, 0x1}, /*40*/ 1744a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // The next 8 are for the bordered version. 1745a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.75, +0.50, 0x3}, /*41*/ 1746a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.50, +0.75, 0x3}, /*42*/ 1747a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.50, +0.75, 0x2}, /*43*/ 1748a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.75, +0.50, 0x2}, /*44*/ 1749a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.75, -0.50, 0x0}, /*45*/ 1750a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.50, -0.75, 0x0}, /*46*/ 1751a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.50, -0.75, 0x1}, /*47*/ 1752a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.75, -0.50, 0x1}, /*48*/ 1753a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1754a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // 16-gon that inscribes the unit circle, cut by an interior unit 16-gon. 1755a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.000000f, +0.000000f, 0}, /*49*/ 1756a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.000000f, +0.198913f, ~0}, /*50*/ 1757a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.923879f, +0.382683f, 0}, /*51*/ 1758a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.847760f, +0.566455f, ~0}, /*52*/ 1759a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.707106f, +0.707106f, 0}, /*53*/ 1760a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.566455f, +0.847760f, ~0}, /*54*/ 1761a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.382683f, +0.923879f, 0}, /*55*/ 1762a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.198913f, +1.000000f, ~0}, /*56*/ 1763a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.000000f, +1.000000f, 0}, /*57*/ 1764a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.198913f, +1.000000f, ~0}, /*58*/ 1765a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.382683f, +0.923879f, 0}, /*59*/ 1766a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.566455f, +0.847760f, ~0}, /*60*/ 1767a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.707106f, +0.707106f, 0}, /*61*/ 1768a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.847760f, +0.566455f, ~0}, /*62*/ 1769a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.923879f, +0.382683f, 0}, /*63*/ 1770a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.000000f, +0.198913f, ~0}, /*64*/ 1771a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.000000f, +0.000000f, 0}, /*65*/ 1772a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-1.000000f, -0.198913f, ~0}, /*66*/ 1773a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.923879f, -0.382683f, 0}, /*67*/ 1774a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.847760f, -0.566455f, ~0}, /*68*/ 1775a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.707106f, -0.707106f, 0}, /*69*/ 1776a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.566455f, -0.847760f, ~0}, /*70*/ 1777a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.382683f, -0.923879f, 0}, /*71*/ 1778a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.198913f, -1.000000f, ~0}, /*72*/ 1779a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {-0.000000f, -1.000000f, 0}, /*73*/ 1780a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.198913f, -1.000000f, ~0}, /*74*/ 1781a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.382683f, -0.923879f, 0}, /*75*/ 1782a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.566455f, -0.847760f, ~0}, /*76*/ 1783a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.707106f, -0.707106f, 0}, /*77*/ 1784a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.847760f, -0.566455f, ~0}, /*78*/ 1785a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+0.923879f, -0.382683f, 0}, /*79*/ 1786a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton {+1.000000f, -0.198913f, ~0}, /*80*/ 1787a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 1788a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1789a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst uint8_t kIndexData[] = { 1790a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Rectangle. 1791a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 0, 1, 2, 1792a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 0, 2, 3, 1793a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1794a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Rectangle with a border. 1795a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 0, 1, 5, 1796a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 5, 4, 0, 1797a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1, 2, 6, 1798a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 6, 5, 1, 1799a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2, 3, 7, 1800a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 7, 6, 2, 1801a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 3, 0, 4, 1802a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 4, 7, 3, 1803a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 4, 5, 6, 1804a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 6, 7, 4, 1805a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1806a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Octagon that inscribes the unit circle, cut by an interior unit octagon. 1807a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 10, 8, 9, 1808a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 12, 10, 11, 1809a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 14, 12, 13, 1810a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 16, 14, 15, 1811a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 18, 16, 17, 1812a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 20, 18, 19, 1813a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 22, 20, 21, 1814a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 8, 22, 23, 1815a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 8, 10, 12, 1816a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 12, 14, 16, 1817a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 16, 18, 20, 1818a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 20, 22, 8, 1819a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 8, 12, 16, 1820a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 16, 20, 8, 1821a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1822a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Same octagons, but with the interior arranged as a fan. Used by mixed samples. 1823a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 10, 8, 9, 1824a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 12, 10, 11, 1825a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 14, 12, 13, 1826a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 16, 14, 15, 1827a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 18, 16, 17, 1828a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 20, 18, 19, 1829a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 22, 20, 21, 1830a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 8, 22, 23, 1831a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 24, 8, 10, 1832a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 12, 24, 10, 1833a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 24, 12, 14, 1834a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 16, 24, 14, 1835a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 24, 16, 18, 1836a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 20, 24, 18, 1837a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 24, 20, 22, 1838a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 8, 24, 22, 1839a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1840a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Same octagons, but with the inner and outer disjoint. Used by coverage AA. 1841a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 8, 22, 23, 1842a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 9, 8, 23, 1843a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 10, 8, 9, 1844a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 11, 10, 9, 1845a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 12, 10, 11, 1846a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 13, 12, 11, 1847a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 14, 12, 13, 1848a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 15, 14, 13, 1849a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 16, 14, 15, 1850a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 17, 16, 15, 1851a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 18, 16, 17, 1852a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 19, 18, 17, 1853a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 20, 18, 19, 1854a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 21, 20, 19, 1855a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 22, 20, 21, 1856a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 23, 22, 21, 1857a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 22, 8, 10, 1858a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 10, 12, 14, 1859a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 14, 16, 18, 1860a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 18, 20, 22, 1861a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 22, 10, 14, 1862a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 14, 18, 22, 1863a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1864a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Rectangle with disjoint corner segments. 1865a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 27, 25, 26, 1866a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 30, 28, 29, 1867a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 33, 31, 32, 1868a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 36, 34, 35, 1869a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 25, 27, 28, 1870a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 28, 30, 31, 1871a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 31, 33, 34, 1872a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 34, 36, 25, 1873a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 25, 28, 31, 1874a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 31, 34, 25, 1875a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1876a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Same rectangle with disjoint corners, but with the interior arranged as a fan. Used by 1877a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // mixed samples. 1878a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 27, 25, 26, 1879a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 30, 28, 29, 1880a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 33, 31, 32, 1881a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 36, 34, 35, 1882a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 27, 37, 25, 1883a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 28, 37, 27, 1884a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 30, 38, 28, 1885a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 31, 38, 30, 1886a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 33, 39, 31, 1887a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 34, 39, 33, 1888a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 36, 40, 34, 1889a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 25, 40, 36, 1890a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1891a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Same rectangle with disjoint corners, with a border as well. Used by coverage AA. 1892a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 41, 25, 26, 1893a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 42, 41, 26, 1894a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 27, 42, 26, 1895a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 43, 28, 29, 1896a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 44, 43, 29, 1897a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 30, 44, 29, 1898a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 45, 31, 32, 1899a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 46, 45, 32, 1900a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 33, 46, 32, 1901a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 47, 34, 35, 1902a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 48, 47, 35, 1903a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 36, 48, 35, 1904a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 27, 28, 42, 1905a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 42, 28, 43, 1906a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 30, 31, 44, 1907a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 44, 31, 45, 1908a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 33, 34, 46, 1909a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 46, 34, 47, 1910a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 36, 25, 48, 1911a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 48, 25, 41, 1912a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 41, 42, 43, 1913a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 43, 44, 45, 1914a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 45, 46, 47, 1915a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 47, 48, 41, 1916a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 41, 43, 45, 1917a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 45, 47, 41, 1918a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1919a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // Same as the disjoint octagons, but with 16-gons instead. Used by coverage AA when the oval is 1920a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // sufficiently large. 1921a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 49, 79, 80, 1922a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 50, 49, 80, 1923a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 51, 49, 50, 1924a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 52, 51, 50, 1925a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 53, 51, 52, 1926a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 54, 53, 52, 1927a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 55, 53, 54, 1928a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 56, 55, 54, 1929a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 57, 55, 56, 1930a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 58, 57, 56, 1931a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 59, 57, 58, 1932a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 60, 59, 58, 1933a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 61, 59, 60, 1934a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 62, 61, 60, 1935a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 63, 61, 62, 1936a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 64, 63, 62, 1937a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 65, 63, 64, 1938a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 66, 65, 64, 1939a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 67, 65, 66, 1940a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 68, 67, 66, 1941a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 69, 67, 68, 1942a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 70, 69, 68, 1943a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 71, 69, 70, 1944a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 72, 71, 70, 1945a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 73, 71, 72, 1946a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 74, 73, 72, 1947a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 75, 73, 74, 1948a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 76, 75, 74, 1949a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 77, 75, 76, 1950a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 78, 77, 76, 1951a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 79, 77, 78, 1952a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 80, 79, 78, 1953a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 49, 51, 53, 1954a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 53, 55, 57, 1955a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 57, 59, 61, 1956a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 61, 63, 65, 1957a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 65, 67, 69, 1958a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 69, 71, 73, 1959a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 73, 75, 77, 1960a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 77, 79, 49, 1961a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 49, 53, 57, 1962a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 57, 61, 65, 1963a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 65, 69, 73, 1964a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 73, 77, 49, 1965a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 49, 57, 65, 1966a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 65, 73, 49, 1967a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 1968a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1969a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonenum { 1970a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kRect_FirstIndex = 0, 1971a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kRect_TriCount = 2, 1972a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1973a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kFramedRect_FirstIndex = 6, 1974a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kFramedRect_TriCount = 10, 1975a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1976a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kOctagons_FirstIndex = 36, 1977a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kOctagons_TriCount = 14, 1978a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1979a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kOctagonsFanned_FirstIndex = 78, 1980a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kOctagonsFanned_TriCount = 16, 1981a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1982a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kDisjointOctagons_FirstIndex = 126, 1983a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kDisjointOctagons_TriCount = 22, 1984a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1985a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kCorneredRect_FirstIndex = 192, 1986a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kCorneredRect_TriCount = 10, 1987a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1988a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kCorneredRectFanned_FirstIndex = 222, 1989a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kCorneredRectFanned_TriCount = 12, 1990a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1991a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kCorneredFramedRect_FirstIndex = 258, 1992a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kCorneredFramedRect_TriCount = 26, 1993a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1994a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kDisjoint16Gons_FirstIndex = 336, 1995a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kDisjoint16Gons_TriCount = 46, 1996a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton}; 1997a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 1998a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGR_DECLARE_STATIC_UNIQUE_KEY(gShapeVertexBufferKey); 1999a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2000a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst GrBuffer* InstanceProcessor::FindOrCreateVertexBuffer(GrGpu* gpu) { 2001a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_DEFINE_STATIC_UNIQUE_KEY(gShapeVertexBufferKey); 2002a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrResourceCache* cache = gpu->getContext()->getResourceCache(); 2003a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (GrGpuResource* cached = cache->findAndRefUniqueResource(gShapeVertexBufferKey)) { 2004a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return static_cast<GrBuffer*>(cached); 2005a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 2006a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (GrBuffer* buffer = gpu->createBuffer(sizeof(kVertexData), kVertex_GrBufferType, 2007a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kStatic_GrAccessPattern, kVertexData)) { 2008a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton buffer->resourcePriv().setUniqueKey(gShapeVertexBufferKey); 2009a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return buffer; 2010a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 2011a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return nullptr; 2012a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2013a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2014a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonGR_DECLARE_STATIC_UNIQUE_KEY(gShapeIndexBufferKey); 2015a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2016a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst GrBuffer* InstanceProcessor::FindOrCreateIndex8Buffer(GrGpu* gpu) { 2017a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GR_DEFINE_STATIC_UNIQUE_KEY(gShapeIndexBufferKey); 2018a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton GrResourceCache* cache = gpu->getContext()->getResourceCache(); 2019a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (GrGpuResource* cached = cache->findAndRefUniqueResource(gShapeIndexBufferKey)) { 2020a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return static_cast<GrBuffer*>(cached); 2021a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 2022a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton if (GrBuffer* buffer = gpu->createBuffer(sizeof(kIndexData), kIndex_GrBufferType, 2023a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton kStatic_GrAccessPattern, kIndexData)) { 2024a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton buffer->resourcePriv().setUniqueKey(gShapeIndexBufferKey); 2025a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return buffer; 2026a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 2027a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return nullptr; 2028a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2029a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2030af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian SalomonIndexRange InstanceProcessor::GetIndexRangeForRect(GrAAType aaType) { 2031af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon switch (aaType) { 2032af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kCoverage: 2033af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon return {kFramedRect_FirstIndex, 3 * kFramedRect_TriCount}; 2034af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kNone: 2035af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kMSAA: 2036af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kMixedSamples: 2037af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon return {kRect_FirstIndex, 3 * kRect_TriCount}; 2038af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon } 2039af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon SkFAIL("Unexpected aa type!"); 2040af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon return {0, 0}; 2041a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2042a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2043af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian SalomonIndexRange InstanceProcessor::GetIndexRangeForOval(GrAAType aaType, const SkRect& devBounds) { 2044af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon if (GrAAType::kCoverage == aaType && devBounds.height() * devBounds.width() >= 256 * 256) { 2045a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton // This threshold was chosen quasi-scientifically on Tegra X1. 2046a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton return {kDisjoint16Gons_FirstIndex, 3 * kDisjoint16Gons_TriCount}; 2047a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 2048a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2049af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon switch (aaType) { 2050af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kNone: 2051af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kMSAA: 2052af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon return {kOctagons_FirstIndex, 3 * kOctagons_TriCount}; 2053af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kCoverage: 2054af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon return {kDisjointOctagons_FirstIndex, 3 * kDisjointOctagons_TriCount}; 2055af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kMixedSamples: 2056af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon return {kOctagonsFanned_FirstIndex, 3 * kOctagonsFanned_TriCount}; 2057af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon } 2058af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon SkFAIL("Unexpected aa type!"); 2059af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon return {0, 0}; 2060a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2061a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2062af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian SalomonIndexRange InstanceProcessor::GetIndexRangeForRRect(GrAAType aaType) { 2063af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon switch (aaType) { 2064af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kNone: 2065af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kMSAA: 2066af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon return {kCorneredRect_FirstIndex, 3 * kCorneredRect_TriCount}; 2067af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kCoverage: 2068af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon return {kCorneredFramedRect_FirstIndex, 3 * kCorneredFramedRect_TriCount}; 2069af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon case GrAAType::kMixedSamples: 2070af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon return {kCorneredRectFanned_FirstIndex, 3 * kCorneredRectFanned_TriCount}; 2071af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon } 2072af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon SkFAIL("Unexpected aa type!"); 2073af9847ee11ae92dbb369cdca3e6d6ae69a62b973Brian Salomon return {0, 0}; 2074a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2075a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2076a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonconst char* InstanceProcessor::GetNameOfIndexRange(IndexRange range) { 2077a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton switch (range.fStart) { 2078a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kRect_FirstIndex: return "basic_rect"; 2079a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kFramedRect_FirstIndex: return "coverage_rect"; 2080a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2081a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kOctagons_FirstIndex: return "basic_oval"; 2082a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kDisjointOctagons_FirstIndex: return "coverage_oval"; 2083a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kDisjoint16Gons_FirstIndex: return "coverage_large_oval"; 2084a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kOctagonsFanned_FirstIndex: return "mixed_samples_oval"; 2085a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2086a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kCorneredRect_FirstIndex: return "basic_round_rect"; 2087a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kCorneredFramedRect_FirstIndex: return "coverage_round_rect"; 2088a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton case kCorneredRectFanned_FirstIndex: return "mixed_samples_round_rect"; 2089a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2090a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton default: return "unknown"; 2091a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton } 2092a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2093a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton 2094a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton} 2095