Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2020 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | #include "src/gpu/tessellate/GrDrawAtlasPathOp.h" |
| 9 | |
| 10 | #include "src/gpu/GrOpFlushState.h" |
| 11 | #include "src/gpu/GrOpsRenderPass.h" |
| 12 | #include "src/gpu/GrProgramInfo.h" |
Robert Phillips | 1a82a4e | 2021-07-01 10:27:44 -0400 | [diff] [blame] | 13 | #include "src/gpu/GrResourceProvider.h" |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 14 | #include "src/gpu/GrVertexWriter.h" |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 15 | #include "src/gpu/GrVx.h" |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 16 | #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" |
| 17 | #include "src/gpu/glsl/GrGLSLGeometryProcessor.h" |
| 18 | #include "src/gpu/glsl/GrGLSLVarying.h" |
| 19 | #include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h" |
| 20 | |
| 21 | namespace { |
| 22 | |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 23 | class DrawAtlasPathShader : public GrGeometryProcessor { |
| 24 | public: |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 25 | DrawAtlasPathShader(const GrTextureProxy* atlasProxy, GrSwizzle swizzle, bool isInverseFill, |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 26 | bool usesLocalCoords, const GrShaderCaps& shaderCaps) |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 27 | : GrGeometryProcessor(kDrawAtlasPathShader_ClassID) |
| 28 | , fAtlasAccess(GrSamplerState::Filter::kNearest, atlasProxy->backendFormat(), swizzle) |
| 29 | , fAtlasDimensions(atlasProxy->backingStoreDimensions()) |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 30 | , fIsInverseFill(isInverseFill) |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 31 | , fUsesLocalCoords(usesLocalCoords) { |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 32 | if (!shaderCaps.vertexIDSupport()) { |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 33 | constexpr static Attribute kUnitCoordAttrib("unitCoord", kFloat2_GrVertexAttribType, |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 34 | kFloat2_GrSLType); |
| 35 | this->setVertexAttributes(&kUnitCoordAttrib, 1); |
| 36 | } |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 37 | fAttribs.emplace_back("fillBounds", kFloat4_GrVertexAttribType, kFloat4_GrSLType); |
| 38 | if (fUsesLocalCoords) { |
| 39 | fAttribs.emplace_back("affineMatrix", kFloat4_GrVertexAttribType, kFloat4_GrSLType); |
| 40 | fAttribs.emplace_back("translate", kFloat2_GrVertexAttribType, kFloat2_GrSLType); |
| 41 | } |
| 42 | SkASSERT(fAttribs.count() == this->colorAttribIdx()); |
| 43 | fAttribs.emplace_back("color", kFloat4_GrVertexAttribType, kHalf4_GrSLType); |
| 44 | fAttribs.emplace_back("locations", kFloat4_GrVertexAttribType, kFloat4_GrSLType); |
| 45 | if (fIsInverseFill) { |
| 46 | fAttribs.emplace_back("sizeInAtlas", kFloat2_GrVertexAttribType, kFloat2_GrSLType); |
| 47 | } |
| 48 | this->setInstanceAttributes(fAttribs.data(), fAttribs.count()); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 49 | this->setTextureSamplerCnt(1); |
| 50 | } |
| 51 | |
| 52 | private: |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 53 | int colorAttribIdx() const { return fUsesLocalCoords ? 3 : 1; } |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 54 | const char* name() const override { return "DrawAtlasPathShader"; } |
| 55 | void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override { |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 56 | b->add32((fUsesLocalCoords << 1) | (int)fIsInverseFill); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 57 | } |
| 58 | const TextureSampler& onTextureSampler(int) const override { return fAtlasAccess; } |
Robert Phillips | f10535f | 2021-03-23 09:30:45 -0400 | [diff] [blame] | 59 | GrGLSLGeometryProcessor* createGLSLInstance(const GrShaderCaps&) const override; |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 60 | |
| 61 | const TextureSampler fAtlasAccess; |
| 62 | const SkISize fAtlasDimensions; |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 63 | const bool fIsInverseFill; |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 64 | const bool fUsesLocalCoords; |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 65 | SkSTArray<6, GrGeometryProcessor::Attribute> fAttribs; |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 66 | |
| 67 | class Impl; |
| 68 | }; |
| 69 | |
| 70 | class DrawAtlasPathShader::Impl : public GrGLSLGeometryProcessor { |
| 71 | void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { |
Robert Phillips | 787fd9d | 2021-03-22 14:48:09 -0400 | [diff] [blame] | 72 | const auto& shader = args.fGeomProc.cast<DrawAtlasPathShader>(); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 73 | args.fVaryingHandler->emitAttributes(shader); |
| 74 | |
| 75 | GrGLSLVarying atlasCoord(kFloat2_GrSLType); |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 76 | args.fVaryingHandler->addVarying("atlasCoord", &atlasCoord); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 77 | |
| 78 | const char* atlasAdjust; |
| 79 | fAtlasAdjustUniform = args.fUniformHandler->addUniform( |
Ethan Nicholas | 16464c3 | 2020-04-06 13:53:05 -0400 | [diff] [blame] | 80 | nullptr, kVertex_GrShaderFlag, kFloat2_GrSLType, "atlas_adjust", &atlasAdjust); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 81 | |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 82 | if (args.fShaderCaps->vertexIDSupport()) { |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 83 | // If we don't have sk_VertexID support then "unitCoord" already came in as a vertex |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 84 | // attrib. |
| 85 | args.fVertBuilder->codeAppendf(R"( |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 86 | float2 unitCoord = float2(sk_VertexID & 1, sk_VertexID >> 1);)"); |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 87 | } |
| 88 | |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 89 | args.fVertBuilder->codeAppendf(R"( |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 90 | float2 devCoord = mix(fillBounds.xy, fillBounds.zw, unitCoord);)"); |
| 91 | gpArgs->fPositionVar.set(kFloat2_GrSLType, "devCoord"); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 92 | |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 93 | if (shader.fUsesLocalCoords) { |
| 94 | args.fVertBuilder->codeAppendf(R"( |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 95 | float2x2 M = float2x2(affineMatrix); |
| 96 | float2 localCoord = inverse(M) * (devCoord - translate);)"); |
| 97 | gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "localCoord"); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 98 | } |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 99 | |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 100 | args.fVertBuilder->codeAppendf(R"( |
| 101 | // A negative x coordinate in the atlas indicates that the path is transposed. |
| 102 | // We also added 1 since we can't negate zero. |
| 103 | float2 atlasTopLeft = float2(abs(locations.x) - 1, locations.y); |
| 104 | float2 devTopLeft = locations.zw; |
| 105 | bool transposed = locations.x < 0; |
| 106 | float2 atlasCoord = devCoord - devTopLeft; |
| 107 | if (transposed) { |
| 108 | atlasCoord = atlasCoord.yx; |
| 109 | } |
| 110 | atlasCoord += atlasTopLeft; |
| 111 | %s = atlasCoord * %s;)", atlasCoord.vsOut(), atlasAdjust); |
| 112 | |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 113 | if (shader.fIsInverseFill) { |
| 114 | GrGLSLVarying atlasBounds(kFloat4_GrSLType); |
| 115 | args.fVaryingHandler->addVarying("atlasbounds", &atlasBounds, |
| 116 | GrGLSLVaryingHandler::Interpolation::kCanBeFlat); |
| 117 | args.fVertBuilder->codeAppendf(R"( |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 118 | float4 atlasBounds = atlasTopLeft.xyxy + (transposed ? sizeInAtlas.00yx |
| 119 | : sizeInAtlas.00xy); |
| 120 | %s = atlasBounds * %s.xyxy;)", atlasBounds.vsOut(), atlasAdjust); |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 121 | |
| 122 | args.fFragBuilder->codeAppendf(R"( |
| 123 | half coverage = 0; |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 124 | float2 atlasCoord = %s; |
| 125 | float4 atlasBounds = %s; |
| 126 | if (all(greaterThan(atlasCoord, atlasBounds.xy)) && |
| 127 | all(lessThan(atlasCoord, atlasBounds.zw))) { |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 128 | coverage = )", atlasCoord.fsIn(), atlasBounds.fsIn()); |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 129 | args.fFragBuilder->appendTextureLookup(args.fTexSamplers[0], "atlasCoord"); |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 130 | args.fFragBuilder->codeAppendf(R"(.a; |
| 131 | } |
| 132 | half4 %s = half4(1 - coverage);)", args.fOutputCoverage); |
| 133 | } else { |
| 134 | args.fFragBuilder->codeAppendf("half4 %s = ", args.fOutputCoverage); |
| 135 | args.fFragBuilder->appendTextureLookup(args.fTexSamplers[0], atlasCoord.fsIn()); |
| 136 | args.fFragBuilder->codeAppendf(".aaaa;"); |
| 137 | } |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 138 | |
| 139 | args.fFragBuilder->codeAppendf("half4 %s;", args.fOutputColor); |
| 140 | args.fVaryingHandler->addPassThroughAttribute( |
| 141 | shader.fAttribs[shader.colorAttribIdx()], args.fOutputColor, |
| 142 | GrGLSLVaryingHandler::Interpolation::kCanBeFlat); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 143 | } |
| 144 | |
Brian Osman | 609f159 | 2020-07-01 15:14:39 -0400 | [diff] [blame] | 145 | void setData(const GrGLSLProgramDataManager& pdman, |
Brian Salomon | 5a32828 | 2021-04-14 10:32:25 -0400 | [diff] [blame] | 146 | const GrShaderCaps&, |
Robert Phillips | 787fd9d | 2021-03-22 14:48:09 -0400 | [diff] [blame] | 147 | const GrGeometryProcessor& geomProc) override { |
| 148 | const SkISize& dimensions = geomProc.cast<DrawAtlasPathShader>().fAtlasDimensions; |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 149 | pdman.set2f(fAtlasAdjustUniform, 1.f / dimensions.width(), 1.f / dimensions.height()); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | GrGLSLUniformHandler::UniformHandle fAtlasAdjustUniform; |
| 153 | }; |
| 154 | |
Robert Phillips | f10535f | 2021-03-23 09:30:45 -0400 | [diff] [blame] | 155 | GrGLSLGeometryProcessor* DrawAtlasPathShader::createGLSLInstance(const GrShaderCaps&) const { |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 156 | return new Impl(); |
| 157 | } |
| 158 | |
| 159 | } // namespace |
| 160 | |
| 161 | GrProcessorSet::Analysis GrDrawAtlasPathOp::finalize(const GrCaps& caps, const GrAppliedClip* clip, |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 162 | GrClampType clampType) { |
| 163 | const GrProcessorSet::Analysis& analysis = fProcessors.finalize( |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 164 | fHeadInstance->fColor, GrProcessorAnalysisCoverage::kSingleChannel, clip, |
| 165 | &GrUserStencilSettings::kUnused, caps, clampType, &fHeadInstance->fColor); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 166 | fUsesLocalCoords = analysis.usesLocalCoords(); |
| 167 | return analysis; |
| 168 | } |
| 169 | |
| 170 | GrOp::CombineResult GrDrawAtlasPathOp::onCombineIfPossible( |
Herb Derby | e25c300 | 2020-10-27 15:57:27 -0400 | [diff] [blame] | 171 | GrOp* op, SkArenaAlloc* alloc, const GrCaps&) { |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 172 | auto* that = op->cast<GrDrawAtlasPathOp>(); |
| 173 | SkASSERT(fAtlasProxy == that->fAtlasProxy); |
| 174 | SkASSERT(fEnableHWAA == that->fEnableHWAA); |
| 175 | |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 176 | if (fIsInverseFill != that->fIsInverseFill || fProcessors != that->fProcessors) { |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 177 | return CombineResult::kCannotCombine; |
| 178 | } |
| 179 | |
| 180 | SkASSERT(fUsesLocalCoords == that->fUsesLocalCoords); |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 181 | *fTailInstance = that->fHeadInstance; |
| 182 | fTailInstance = that->fTailInstance; |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 183 | fInstanceCount += that->fInstanceCount; |
| 184 | return CombineResult::kMerged; |
| 185 | } |
| 186 | |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 187 | void GrDrawAtlasPathOp::prepareProgram(const GrCaps& caps, SkArenaAlloc* arena, |
| 188 | const GrSurfaceProxyView& writeView, |
| 189 | GrAppliedClip&& appliedClip, |
| 190 | const GrDstProxyView& dstProxyView, |
| 191 | GrXferBarrierFlags renderPassXferBarriers, |
| 192 | GrLoadOp colorLoadOp) { |
| 193 | SkASSERT(!fProgram); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 194 | GrPipeline::InitArgs initArgs; |
| 195 | if (fEnableHWAA) { |
| 196 | initArgs.fInputFlags |= GrPipeline::InputFlags::kHWAntialias; |
| 197 | } |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 198 | initArgs.fCaps = ∩︀ |
| 199 | initArgs.fDstProxyView = dstProxyView; |
| 200 | initArgs.fWriteSwizzle = writeView.swizzle(); |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 201 | auto pipeline = arena->make<GrPipeline>(initArgs, std::move(fProcessors), |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 202 | std::move(appliedClip)); |
| 203 | GrSwizzle swizzle = caps.getReadSwizzle(fAtlasProxy->backendFormat(), GrColorType::kAlpha_8); |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 204 | auto shader = arena->make<DrawAtlasPathShader>(fAtlasProxy.get(), swizzle, fIsInverseFill, |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 205 | fUsesLocalCoords, *caps.shaderCaps()); |
| 206 | fProgram = arena->make<GrProgramInfo>(writeView, pipeline, &GrUserStencilSettings::kUnused, |
| 207 | shader, GrPrimitiveType::kTriangleStrip, 0, |
| 208 | renderPassXferBarriers, colorLoadOp); |
| 209 | } |
Chris Dalton | 012f849 | 2020-03-05 11:49:15 -0700 | [diff] [blame] | 210 | |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 211 | void GrDrawAtlasPathOp::onPrePrepare(GrRecordingContext* rContext, |
| 212 | const GrSurfaceProxyView& writeView, |
| 213 | GrAppliedClip* appliedClip, const GrDstProxyView& dstProxyView, |
| 214 | GrXferBarrierFlags renderPassXferBarriers, |
| 215 | GrLoadOp colorLoadOp) { |
| 216 | this->prepareProgram(*rContext->priv().caps(), rContext->priv().recordTimeAllocator(), |
| 217 | writeView, std::move(*appliedClip), dstProxyView, renderPassXferBarriers, |
| 218 | colorLoadOp); |
| 219 | SkASSERT(fProgram); |
| 220 | rContext->priv().recordProgramInfo(fProgram); |
| 221 | } |
| 222 | |
| 223 | GR_DECLARE_STATIC_UNIQUE_KEY(gUnitQuadBufferKey); |
| 224 | |
| 225 | void GrDrawAtlasPathOp::onPrepare(GrOpFlushState* flushState) { |
| 226 | if (!fProgram) { |
| 227 | this->prepareProgram(flushState->caps(), flushState->allocator(), flushState->writeView(), |
| 228 | flushState->detachAppliedClip(), flushState->dstProxyView(), |
| 229 | flushState->renderPassBarriers(), flushState->colorLoadOp()); |
| 230 | SkASSERT(fProgram); |
| 231 | } |
| 232 | |
| 233 | if (GrVertexWriter instanceWriter = flushState->makeVertexSpace( |
| 234 | fProgram->geomProc().instanceStride(), fInstanceCount, &fInstanceBuffer, |
| 235 | &fBaseInstance)) { |
| 236 | for (const Instance* instance = fHeadInstance; instance; instance = instance->fNext) { |
| 237 | SkASSERT(instance->fLocationInAtlas.x() >= 0); |
| 238 | SkASSERT(instance->fLocationInAtlas.y() >= 0); |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 239 | instanceWriter.write( |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 240 | SkRect::Make(instance->fFillBounds), |
| 241 | GrVertexWriter::If(fUsesLocalCoords, |
| 242 | instance->fLocalToDeviceIfUsingLocalCoords), |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 243 | instance->fColor, |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 244 | // A negative x coordinate in the atlas indicates that the path is transposed. |
| 245 | // Also add 1 since we can't negate zero. |
| 246 | (float)(instance->fTransposedInAtlas ? -instance->fLocationInAtlas.x() - 1 |
| 247 | : instance->fLocationInAtlas.x() + 1), |
| 248 | (float)instance->fLocationInAtlas.y(), |
| 249 | (float)instance->fPathDevIBounds.left(), |
| 250 | (float)instance->fPathDevIBounds.top(), |
| 251 | GrVertexWriter::If(fIsInverseFill, |
| 252 | SkSize::Make(instance->fPathDevIBounds.size()))); |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 253 | } |
| 254 | } |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 255 | |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 256 | if (!flushState->caps().shaderCaps()->vertexIDSupport()) { |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 257 | constexpr static SkPoint kUnitQuad[4] = {{0,0}, {0,1}, {1,0}, {1,1}}; |
| 258 | |
| 259 | GR_DEFINE_STATIC_UNIQUE_KEY(gUnitQuadBufferKey); |
| 260 | |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 261 | fVertexBufferIfNoIDSupport = flushState->resourceProvider()->findOrMakeStaticBuffer( |
Chris Dalton | a05ccc3 | 2021-06-29 19:42:13 -0600 | [diff] [blame] | 262 | GrGpuBufferType::kVertex, sizeof(kUnitQuad), kUnitQuad, gUnitQuadBufferKey); |
| 263 | } |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 264 | } |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 265 | |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 266 | void GrDrawAtlasPathOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) { |
Chris Dalton | baae2dd | 2021-06-25 14:52:49 -0600 | [diff] [blame] | 267 | SkASSERT(fAtlasProxy->isInstantiated()); |
Chris Dalton | ee40d5a | 2021-07-07 16:34:36 -0600 | [diff] [blame] | 268 | flushState->bindPipelineAndScissorClip(*fProgram, this->bounds()); |
| 269 | flushState->bindTextures(fProgram->geomProc(), *fAtlasProxy, fProgram->pipeline()); |
| 270 | flushState->bindBuffers(nullptr, std::move(fInstanceBuffer), fVertexBufferIfNoIDSupport); |
| 271 | flushState->drawInstanced(fInstanceCount, fBaseInstance, 4, 0); |
Chris Dalton | 4e99853 | 2020-02-10 11:06:42 -0700 | [diff] [blame] | 272 | } |