272 {
273
276 const bool useStepStorageBuffer = useStorageBuffers && hasStepUniforms;
277 const bool useShadingStorageBuffer = useStorageBuffers &&
step->performsShading();
278
281 "in",
282 useShadingStorageBuffer,
283 defineLocalCoordsVarying);
284
285
286
287
288
289 const ResourceBindingRequirements& bindingReqs = caps->resourceBindingRequirements();
290 if (hasStepUniforms) {
291 if (useStepStorageBuffer) {
293 } else {
295 bindingReqs.fUniformBufferLayout,
297 renderStepUniformTotalBytes);
298 }
299 }
300
301 bool wrotePaintColor = false;
302 if (useShadingStorageBuffer) {
304 fRootNodes,
305 numPaintUniforms,
306 &wrotePaintColor);
308 } else {
310 bindingReqs.fUniformBufferLayout,
311 fRootNodes,
312 numPaintUniforms,
313 paintUniformsTotalBytes,
314 &wrotePaintColor);
315 }
316
317 {
318 int binding = 0;
320 if (
step->hasTextures()) {
321 preamble +=
step->texturesAndSamplersSkSL(bindingReqs, &binding);
322 }
323
324
325 if (numTexturesAndSamplersUsed) {
326 *numTexturesAndSamplersUsed = binding;
327 }
328 }
329
330 if (
step->emitsPrimitiveColor()) {
331
332
333 preamble += "half4 primitiveColor;";
334 }
335
336
337
338
339 emit_preambles(*this, fRootNodes, "", &preamble);
340
341 std::string mainBody = "void main() {";
342
343
344 mainBody += "half4 initialColor = half4(0);";
345
346 if (useShadingStorageBuffer) {
348 "%s = %s.y;\n",
351 }
352
353 if (
step->emitsPrimitiveColor()) {
354 mainBody +=
step->fragmentColorSkSL();
355 }
356
357
358
359 const ShaderNode* clipShaderNode = nullptr;
360
361
362
363 static constexpr char kUnusedDstColor[] = "half4(1)";
364 static constexpr char kUnusedLocalCoords[] = "float2(0)";
365 ShaderSnippet::Args
args = {
"initialColor",
366 kUnusedDstColor,
368 for (const ShaderNode* node : fRootNodes) {
371 clipShaderNode = node;
372 continue;
373 }
374
375
378 args.fPriorStageOutput = emit_glue_code_for_entry(*
this, node,
args, &mainBody);
379 }
380 }
381
384 args.fPriorStageOutput.c_str(),
385 writeSwizzle.asString().c_str());
386 }
387
388 const char* outColor =
args.fPriorStageOutput.c_str();
391 if (useStepStorageBuffer) {
393 "uint stepSsboIndex = %s.x;\n",
396 }
397
398 mainBody += "half4 outputCoverage = half4(1);";
399 mainBody +=
step->fragmentCoverageSkSL();
400
401 if (clipShaderNode) {
402 std::string clipShaderOutput =
403 emit_glue_code_for_entry(*
this, clipShaderNode,
args, &mainBody);
405 }
406
407
408 BlendFormula coverageBlendFormula =
413
415
416
417
418
419
423
424
425
426
427
428 mainBody +=
429 "if (all(lessThanEqual(outputCoverage.rgb, half3(0)))) {"
430 "discard;"
431 "}";
432 }
433
434
436 &mainBody,
437 "sk_FragColor = %s * outputCoverage + surfaceColor * (1.0 - outputCoverage);",
438 outColor);
441 &mainBody,
442 "half3 lerpRGB = mix(surfaceColor.aaa, %s.aaa, outputCoverage.rgb);"
443 "sk_FragColor.a = max(max(lerpRGB.r, lerpRGB.g), lerpRGB.b);",
444 outColor);
445 }
446
447 } else {
448 fBlendInfo = {coverageBlendFormula.equation(),
449 coverageBlendFormula.srcCoeff(),
450 coverageBlendFormula.dstCoeff(),
452 coverageBlendFormula.modifiesDst()};
453
455 mainBody += "outputCoverage.a = max(max(outputCoverage.r, "
456 "outputCoverage.g), "
457 "outputCoverage.b);";
458 }
460 &mainBody, coverageBlendFormula.primaryOutput(), "sk_FragColor", outColor);
461 if (coverageBlendFormula.hasSecondaryOutput()) {
463 coverageBlendFormula.secondaryOutput(),
464 "sk_SecondaryFragColor",
465 outColor);
466 }
467 }
468
469 } else {
471 }
472 mainBody += "}\n";
473
474 return preamble + "\n" + mainBody;
475}
static int step(int x, SkScalar min, SkScalar max)
constexpr SkPMColor4f SK_PMColor4fTRANSPARENT
static constexpr Swizzle RGBA()
static const char * ssboIndicesVarying()
const char * ssboIndex() const
bool needsLocalCoords() const
bool needsSurfaceColor() const
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
std::string void appendf(std::string *str, const char *fmt,...) SK_PRINTF_LIKE(2
std::string EmitPaintParamsUniforms(int bufferID, const Layout layout, SkSpan< const ShaderNode * > nodes, int *numUniforms, int *uniformsTotalBytes, bool *wrotePaintColor)
std::string EmitTexturesAndSamplers(const ResourceBindingRequirements &bindingReqs, SkSpan< const ShaderNode * > nodes, int *binding)
std::string EmitRenderStepStorageBuffer(int bufferID, SkSpan< const Uniform > uniforms)
std::string EmitRenderStepUniforms(int bufferID, const Layout layout, SkSpan< const Uniform > uniforms, int *renderStepUniformsTotalBytes)
std::string EmitVaryings(const RenderStep *step, const char *direction, bool emitSsboIndicesVarying, bool emitLocalCoordsVarying)
std::string EmitPaintParamsStorageBuffer(int bufferID, SkSpan< const ShaderNode * > nodes, int *numUniforms, bool *wrotePaintColor)
void append_color_output(std::string *mainBody, BlendFormula::OutputType outputType, const char *outColor, const char *inColor)
std::string EmitUniformsFromStorageBuffer(const char *bufferNamePrefix, const char *ssboIndex, SkSpan< const Uniform > uniforms)
BlendFormula GetBlendFormula(bool isOpaque, bool hasCoverage, SkBlendMode xfermode)
BlendFormula GetLCDBlendFormula(SkBlendMode xfermode)