Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Namespaces | Macros | Functions
Main.cpp File Reference
#include "include/core/SkGraphics.h"
#include "include/core/SkStream.h"
#include "src/base/SkStringView.h"
#include "src/core/SkCpu.h"
#include "src/core/SkOpts.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLFileOutputStream.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/SkSLStringStream.h"
#include "src/sksl/SkSLUtil.h"
#include "src/sksl/codegen/SkSLGLSLCodeGenerator.h"
#include "src/sksl/codegen/SkSLHLSLCodeGenerator.h"
#include "src/sksl/codegen/SkSLMetalCodeGenerator.h"
#include "src/sksl/codegen/SkSLPipelineStageCodeGenerator.h"
#include "src/sksl/codegen/SkSLRasterPipelineBuilder.h"
#include "src/sksl/codegen/SkSLRasterPipelineCodeGenerator.h"
#include "src/sksl/codegen/SkSLSPIRVCodeGenerator.h"
#include "src/sksl/codegen/SkSLWGSLCodeGenerator.h"
#include "src/sksl/ir/SkSLFunctionDeclaration.h"
#include "src/sksl/ir/SkSLProgram.h"
#include "src/sksl/ir/SkSLVarDeclarations.h"
#include "src/sksl/tracing/SkSLDebugTracePriv.h"
#include "src/utils/SkShaderUtils.h"
#include "tools/skslc/ProcessWorklist.h"
#include "spirv-tools/libspirv.hpp"
#include <fstream>
#include <limits.h>
#include <optional>
#include <stdarg.h>
#include <stdio.h>

Go to the source code of this file.

Classes

class  ShaderCapsTestFactory
 

Namespaces

namespace  SkOpts
 

Macros

#define SK_OPTS_NS   skslc_standalone
 

Functions

void SkDebugf (const char format[],...)
 
static std::unique_ptr< SkWStreamas_SkWStream (SkSL::OutputStream &s)
 
static bool consume_suffix (std::string *str, const char suffix[])
 
static bool detect_shader_settings (const std::string &text, SkSL::ProgramSettings *settings, const SkSL::ShaderCaps **caps, std::unique_ptr< SkSL::DebugTracePriv > *debugTrace)
 
static void show_usage ()
 
static bool set_flag (std::optional< bool > *flag, const char *name, bool value)
 
static ResultCode process_command (SkSpan< std::string > args)
 
int main (int argc, const char **argv)
 

Macro Definition Documentation

◆ SK_OPTS_NS

#define SK_OPTS_NS   skslc_standalone

Definition at line 8 of file Main.cpp.

Function Documentation

◆ as_SkWStream()

static std::unique_ptr< SkWStream > as_SkWStream ( SkSL::OutputStream s)
static

Definition at line 53 of file Main.cpp.

53 {
54 struct Adapter : public SkWStream {
55 public:
56 Adapter(SkSL::OutputStream& out) : fOut(out), fBytesWritten(0) {}
57
58 bool write(const void* buffer, size_t size) override {
59 fOut.write(buffer, size);
60 fBytesWritten += size;
61 return true;
62 }
63 void flush() override {}
64 size_t bytesWritten() const override { return fBytesWritten; }
65
66 private:
68 size_t fBytesWritten;
69 };
70
71 return std::make_unique<Adapter>(s);
72}
virtual bool write(const void *buffer, size_t size)=0
virtual void flush()
Definition SkStream.cpp:77
virtual size_t bytesWritten() const =0
struct MyStruct s
static const uint8_t buffer[]
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259

◆ consume_suffix()

static bool consume_suffix ( std::string *  str,
const char  suffix[] 
)
static

Definition at line 74 of file Main.cpp.

74 {
75 if (!skstd::ends_with(*str, suffix)) {
76 return false;
77 }
78 str->resize(str->length() - strlen(suffix));
79 return true;
80}
constexpr bool ends_with(std::string_view str, std::string_view suffix)

◆ detect_shader_settings()

static bool detect_shader_settings ( const std::string &  text,
SkSL::ProgramSettings settings,
const SkSL::ShaderCaps **  caps,
std::unique_ptr< SkSL::DebugTracePriv > *  debugTrace 
)
static

Definition at line 347 of file Main.cpp.

350 {
352
353 // Find a matching comment and isolate the name portion.
354 static constexpr char kPragmaSettings[] = "/*#pragma settings ";
355 const char* settingsPtr = strstr(text.c_str(), kPragmaSettings);
356 if (settingsPtr != nullptr) {
357 // Subtract one here in order to preserve the leading space, which is necessary to allow
358 // consumeSuffix to find the first item.
359 settingsPtr += strlen(kPragmaSettings) - 1;
360
361 const char* settingsEnd = strstr(settingsPtr, "*/");
362 if (settingsEnd != nullptr) {
363 std::string settingsText{settingsPtr, size_t(settingsEnd - settingsPtr)};
364
365 // Apply settings as requested. Since they can come in any order, repeat until we've
366 // consumed them all.
367 for (;;) {
368 const size_t startingLength = settingsText.length();
369
370 if (consume_suffix(&settingsText, " AddAndTrueToLoopCondition")) {
371 *caps = Factory::AddAndTrueToLoopCondition();
372 }
373 if (consume_suffix(&settingsText, " CannotUseFractForNegativeValues")) {
374 *caps = Factory::CannotUseFractForNegativeValues();
375 }
376 if (consume_suffix(&settingsText, " CannotUseFragCoord")) {
377 *caps = Factory::CannotUseFragCoord();
378 }
379 if (consume_suffix(&settingsText, " CannotUseMinAndAbsTogether")) {
380 *caps = Factory::CannotUseMinAndAbsTogether();
381 }
382 if (consume_suffix(&settingsText, " CannotUseVoidInSequenceExpressions")) {
383 *caps = Factory::CannotUseVoidInSequenceExpressions();
384 }
385 if (consume_suffix(&settingsText, " DualSourceBlending")) {
386 *caps = Factory::DualSourceBlending();
387 }
388 if (consume_suffix(&settingsText, " Default")) {
389 *caps = Factory::Default();
390 }
391 if (consume_suffix(&settingsText, " EmulateAbsIntFunction")) {
392 *caps = Factory::EmulateAbsIntFunction();
393 }
394 if (consume_suffix(&settingsText, " FramebufferFetchSupport")) {
395 *caps = Factory::FramebufferFetchSupport();
396 }
397 if (consume_suffix(&settingsText, " MustGuardDivisionEvenAfterExplicitZeroCheck")) {
398 *caps = Factory::MustGuardDivisionEvenAfterExplicitZeroCheck();
399 }
400 if (consume_suffix(&settingsText, " MustDeclareFragmentFrontFacing")) {
401 *caps = Factory::MustDeclareFragmentFrontFacing();
402 }
403 if (consume_suffix(&settingsText, " MustForceNegatedAtanParamToFloat")) {
404 *caps = Factory::MustForceNegatedAtanParamToFloat();
405 }
406 if (consume_suffix(&settingsText, " MustForceNegatedLdexpParamToMultiply")) {
407 *caps = Factory::MustForceNegatedLdexpParamToMultiply();
408 }
409 if (consume_suffix(&settingsText, " NoBuiltinDeterminantSupport")) {
410 *caps = Factory::NoBuiltinDeterminantSupport();
411 }
412 if (consume_suffix(&settingsText, " NoBuiltinFMASupport")) {
413 *caps = Factory::NoBuiltinFMASupport();
414 }
415 if (consume_suffix(&settingsText, " NoExternalTextureSupport")) {
416 *caps = Factory::NoExternalTextureSupport();
417 }
418 if (consume_suffix(&settingsText, " RemovePowWithConstantExponent")) {
419 *caps = Factory::RemovePowWithConstantExponent();
420 }
421 if (consume_suffix(&settingsText, " RewriteDoWhileLoops")) {
422 *caps = Factory::RewriteDoWhileLoops();
423 }
424 if (consume_suffix(&settingsText, " RewriteSwitchStatements")) {
425 *caps = Factory::RewriteSwitchStatements();
426 }
427 if (consume_suffix(&settingsText, " RewriteMatrixVectorMultiply")) {
428 *caps = Factory::RewriteMatrixVectorMultiply();
429 }
430 if (consume_suffix(&settingsText, " RewriteMatrixComparisons")) {
431 *caps = Factory::RewriteMatrixComparisons();
432 }
433 if (consume_suffix(&settingsText, " ShaderDerivativeExtensionString")) {
434 *caps = Factory::ShaderDerivativeExtensionString();
435 }
436 if (consume_suffix(&settingsText, " UnfoldShortCircuitAsTernary")) {
437 *caps = Factory::UnfoldShortCircuitAsTernary();
438 }
439 if (consume_suffix(&settingsText, " UsesPrecisionModifiers")) {
440 *caps = Factory::UsesPrecisionModifiers();
441 }
442 if (consume_suffix(&settingsText, " Version110")) {
443 *caps = Factory::Version110();
444 }
445 if (consume_suffix(&settingsText, " Version450Core")) {
446 *caps = Factory::Version450Core();
447 }
448 if (consume_suffix(&settingsText, " AllowNarrowingConversions")) {
449 settings->fAllowNarrowingConversions = true;
450 }
451 if (consume_suffix(&settingsText, " ForceHighPrecision")) {
452 settings->fForceHighPrecision = true;
453 }
454 if (consume_suffix(&settingsText, " NoInline")) {
455 settings->fInlineThreshold = 0;
456 }
457 if (consume_suffix(&settingsText, " NoOptimize")) {
458 settings->fOptimize = false;
459 settings->fInlineThreshold = 0;
460 }
461 if (consume_suffix(&settingsText, " NoRTFlip")) {
462 settings->fForceNoRTFlip = true;
463 }
464 if (consume_suffix(&settingsText, " InlineThresholdMax")) {
465 settings->fInlineThreshold = INT_MAX;
466 }
467 if (consume_suffix(&settingsText, " Sharpen")) {
468 settings->fSharpenTextures = true;
469 }
470 if (consume_suffix(&settingsText, " DebugTrace")) {
471 settings->fOptimize = false;
472 *debugTrace = std::make_unique<SkSL::DebugTracePriv>();
473 }
474
475 if (settingsText.empty()) {
476 break;
477 }
478 if (settingsText.length() == startingLength) {
479 printf("Unrecognized #pragma settings: %s\n", settingsText.c_str());
480 return false;
481 }
482 }
483 }
484 }
485
486 return true;
487}
std::u16string text
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
SKSHAPER_API sk_sp< Factory > Factory()
static bool consume_suffix(std::string *str, const char suffix[])
Definition Main.cpp:74

◆ main()

int main ( int  argc,
const char **  argv 
)

Definition at line 787 of file Main.cpp.

787 {
788 if (argc == 2) {
789 // Worklists are the only two-argument case for skslc, and we don't intend to support
790 // nested worklists, so we can process them here.
791 return (int)ProcessWorklist(argv[1], process_command);
792 } else {
793 // Process non-worklist inputs.
794 std::vector<std::string> args;
795 for (int index=0; index<argc; ++index) {
796 args.push_back(argv[index]);
797 }
798
799 return (int)process_command(args);
800 }
801}
ResultCode ProcessWorklist(const char *worklistPath, const std::function< ResultCode(SkSpan< std::string > args)> &processCommandFn)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static ResultCode process_command(SkSpan< std::string > args)
Definition Main.cpp:513

◆ process_command()

static ResultCode process_command ( SkSpan< std::string >  args)
static

Handle a single input.

Definition at line 513 of file Main.cpp.

513 {
514 std::optional<bool> honorSettings;
515 std::vector<std::string> paths;
516 for (size_t i = 1; i < args.size(); ++i) {
517 const std::string& arg = args[i];
518 if (arg == "--settings") {
519 if (!set_flag(&honorSettings, "settings", true)) {
521 }
522 } else if (arg == "--nosettings") {
523 if (!set_flag(&honorSettings, "settings", false)) {
525 }
526 } else if (!skstd::starts_with(arg, "--")) {
527 paths.push_back(arg);
528 } else {
529 show_usage();
531 }
532 }
533 if (paths.size() != 2) {
534 show_usage();
536 }
537
538 if (!honorSettings.has_value()) {
539 honorSettings = true;
540 }
541
542 const std::string& inputPath = paths[0];
543 const std::string& outputPath = paths[1];
545 if (skstd::ends_with(inputPath, ".vert")) {
547 } else if (skstd::ends_with(inputPath, ".frag") || skstd::ends_with(inputPath, ".sksl")) {
549 } else if (skstd::ends_with(inputPath, ".mvert")) {
551 } else if (skstd::ends_with(inputPath, ".mfrag")) {
553 } else if (skstd::ends_with(inputPath, ".compute")) {
555 } else if (skstd::ends_with(inputPath, ".rtb")) {
557 } else if (skstd::ends_with(inputPath, ".rtcf")) {
559 } else if (skstd::ends_with(inputPath, ".rts")) {
561 } else {
562 printf("input filename must end in '.vert', '.frag', '.mvert', '.mfrag', '.compute', "
563 "'.rtb', '.rtcf', '.rts' or '.sksl'\n");
565 }
566
567 std::ifstream in(inputPath);
568 std::string text((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
569 if (in.rdstate()) {
570 printf("error reading '%s'\n", inputPath.c_str());
572 }
573
576 std::unique_ptr<SkSL::DebugTracePriv> debugTrace;
577 if (*honorSettings) {
578 if (!detect_shader_settings(text, &settings, &caps, &debugTrace)) {
580 }
581 }
582
583 // This tells the compiler where the rt-flip uniform will live should it be required. For
584 // testing purposes we don't care where that is, but the compiler will report an error if we
585 // leave them at their default invalid values, or if the offset overlaps another uniform.
586 settings.fRTFlipOffset = 16384;
587 settings.fRTFlipSet = 0;
588 settings.fRTFlipBinding = 0;
589
590 auto emitCompileError = [&](const char* errorText) {
591 // Overwrite the compiler output, if any, with an error message.
592 SkSL::FileOutputStream errorStream(outputPath.c_str());
593 errorStream.writeText("### Compilation failed:\n\n");
594 errorStream.writeText(errorText);
595 errorStream.close();
596 // Also emit the error directly to stdout.
597 puts(errorText);
598 };
599
600 auto compileProgram = [&](const auto& writeFn) -> ResultCode {
601 SkSL::FileOutputStream out(outputPath.c_str());
603 if (!out.isValid()) {
604 printf("error writing '%s'\n", outputPath.c_str());
606 }
607 std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, text, settings);
608 if (!program || !writeFn(compiler, caps, *program, out)) {
609 out.close();
610 emitCompileError(compiler.errorText().c_str());
612 }
613 if (!out.close()) {
614 printf("error writing '%s'\n", outputPath.c_str());
616 }
618 };
619
620 auto compileProgramAsRuntimeShader = [&](const auto& writeFn) -> ResultCode {
621 if (kind == SkSL::ProgramKind::kVertex) {
622 emitCompileError("Runtime shaders do not support vertex programs\n");
624 }
625 if (kind == SkSL::ProgramKind::kFragment) {
626 // Handle .sksl and .frag programs as runtime shaders.
628 }
629 return compileProgram(writeFn);
630 };
631
632 if (skstd::ends_with(outputPath, ".spirv")) {
633 return compileProgram([](SkSL::Compiler& compiler,
634 const SkSL::ShaderCaps* shaderCaps,
635 SkSL::Program& program,
636 SkSL::OutputStream& out) {
637 return SkSL::ToSPIRV(program, shaderCaps, out);
638 });
639 } else if (skstd::ends_with(outputPath, ".asm.frag") ||
640 skstd::ends_with(outputPath, ".asm.vert") ||
641 skstd::ends_with(outputPath, ".asm.comp")) {
642 return compileProgram(
644 const SkSL::ShaderCaps* shaderCaps,
645 SkSL::Program& program,
646 SkSL::OutputStream& out) {
647 // Compile program to SPIR-V assembly in a string-stream.
648 SkSL::StringStream assembly;
649 if (!SkSL::ToSPIRV(program, shaderCaps, assembly)) {
650 return false;
651 }
652 // Convert the string-stream to a SPIR-V disassembly.
653 spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0);
654 const std::string& spirv(assembly.str());
655 std::string disassembly;
656 uint32_t options = spvtools::SpirvTools::kDefaultDisassembleOption;
657 options |= SPV_BINARY_TO_TEXT_OPTION_INDENT;
658 if (!tools.Disassemble((const uint32_t*)spirv.data(),
659 spirv.size() / 4,
660 &disassembly,
661 options)) {
662 return false;
663 }
664 // Finally, write the disassembly to our output stream.
665 out.write(disassembly.data(), disassembly.size());
666 return true;
667 });
668 } else if (skstd::ends_with(outputPath, ".glsl")) {
669 return compileProgram(
671 const SkSL::ShaderCaps* shaderCaps,
672 SkSL::Program& program,
673 SkSL::OutputStream& out) { return SkSL::ToGLSL(program, shaderCaps, out); });
674 } else if (skstd::ends_with(outputPath, ".metal")) {
675 return compileProgram(
677 const SkSL::ShaderCaps* shaderCaps,
678 SkSL::Program& program,
679 SkSL::OutputStream& out) { return SkSL::ToMetal(program, shaderCaps, out); });
680 } else if (skstd::ends_with(outputPath, ".hlsl")) {
681 return compileProgram(
683 const SkSL::ShaderCaps* shaderCaps,
684 SkSL::Program& program,
685 SkSL::OutputStream& out) { return SkSL::ToHLSL(program, shaderCaps, out); });
686 } else if (skstd::ends_with(outputPath, ".wgsl")) {
687 return compileProgram(
689 const SkSL::ShaderCaps* shaderCaps,
690 SkSL::Program& program,
691 SkSL::OutputStream& out) { return SkSL::ToWGSL(program, shaderCaps, out); });
692 } else if (skstd::ends_with(outputPath, ".skrp")) {
693 settings.fMaxVersionAllowed = SkSL::Version::k300;
694 return compileProgramAsRuntimeShader([&](SkSL::Compiler& compiler,
695 const SkSL::ShaderCaps* shaderCaps,
696 SkSL::Program& program,
697 SkSL::OutputStream& out) {
698 SkSL::DebugTracePriv skrpDebugTrace;
699 const SkSL::FunctionDeclaration* main = program.getFunction("main");
700 if (!main) {
701 compiler.errorReporter().error({}, "code has no entrypoint");
702 return false;
703 }
704 bool wantTraceOps = (debugTrace != nullptr);
705 std::unique_ptr<SkSL::RP::Program> rasterProg = SkSL::MakeRasterPipelineProgram(
706 program, *main->definition(), &skrpDebugTrace, wantTraceOps);
707 if (!rasterProg) {
708 compiler.errorReporter().error({}, "code is not supported");
709 return false;
710 }
711 rasterProg->dump(as_SkWStream(out).get(), /*writeInstructionCount=*/true);
712 return true;
713 });
714 } else if (skstd::ends_with(outputPath, ".stage")) {
715 return compileProgram([](SkSL::Compiler&,
716 const SkSL::ShaderCaps* shaderCaps,
717 SkSL::Program& program,
718 SkSL::OutputStream& out) {
719 class Callbacks : public SkSL::PipelineStage::Callbacks {
720 public:
721 std::string getMangledName(const char* name) override {
722 return std::string(name) + "_0";
723 }
724
725 std::string declareUniform(const SkSL::VarDeclaration* decl) override {
726 fOutput += decl->description();
727 return std::string(decl->var()->name());
728 }
729
730 void defineFunction(const char* decl, const char* body, bool /*isMain*/) override {
731 fOutput += std::string(decl) + '{' + body + '}';
732 }
733
734 void declareFunction(const char* decl) override { fOutput += decl; }
735
736 void defineStruct(const char* definition) override { fOutput += definition; }
737
738 void declareGlobal(const char* declaration) override { fOutput += declaration; }
739
740 std::string sampleShader(int index, std::string coords) override {
741 return "child_" + std::to_string(index) + ".eval(" + coords + ')';
742 }
743
744 std::string sampleColorFilter(int index, std::string color) override {
745 return "child_" + std::to_string(index) + ".eval(" + color + ')';
746 }
747
748 std::string sampleBlender(int index, std::string src, std::string dst) override {
749 return "child_" + std::to_string(index) + ".eval(" + src + ", " + dst + ')';
750 }
751
752 std::string toLinearSrgb(std::string color) override {
753 return "toLinearSrgb(" + color + ')';
754 }
755 std::string fromLinearSrgb(std::string color) override {
756 return "fromLinearSrgb(" + color + ')';
757 }
758
759 std::string fOutput;
760 };
761 // The .stage output looks almost like valid SkSL, but not quite.
762 // The PipelineStageGenerator bridges the gap between the SkSL in `program`,
763 // and the C++ FP builder API (see GrSkSLFP). In that API, children don't need
764 // to be declared (so they don't emit declarations here). Children are sampled
765 // by index, not name - so all children here are just "child_N".
766 // The input color and coords have names in the original SkSL (as parameters to
767 // main), but those are ignored here. References to those variables become
768 // "_coords" and "_inColor". At runtime, those variable names are irrelevant
769 // when the new SkSL is emitted inside the FP - references to those variables
770 // are replaced with strings from EmitArgs, and might be varyings or differently
771 // named parameters.
772 Callbacks callbacks;
773 SkSL::PipelineStage::ConvertProgram(program, "_coords", "_inColor",
774 "_canvasColor", &callbacks);
775 out.writeString(SkShaderUtils::PrettyPrint(callbacks.fOutput));
776 return true;
777 });
778 } else {
779 printf("expected output path to end with one of: .glsl, .html, .metal, .hlsl, .wgsl, "
780 ".spirv, .asm.vert, .asm.frag, .asm.comp, .skrp, .stage (got '%s')\n",
781 outputPath.c_str());
783 }
785}
const char * options
SkColor4f color
ResultCode
@ kConfigurationError
virtual std::string sampleShader(int index, std::string coords)=0
virtual std::string sampleBlender(int index, std::string src, std::string dst)=0
virtual void defineStruct(const char *definition)=0
virtual void declareFunction(const char *declaration)=0
virtual std::string toLinearSrgb(std::string color)=0
virtual void declareGlobal(const char *declaration)=0
virtual std::string sampleColorFilter(int index, std::string color)=0
virtual std::string fromLinearSrgb(std::string color)=0
virtual void defineFunction(const char *declaration, const char *body, bool isMain)=0
virtual std::string declareUniform(const VarDeclaration *)=0
virtual std::string getMangledName(const char *name)
static const ShaderCaps * Standalone()
Definition SkSLUtil.h:176
const std::string & str() const
std::string_view name() const
Definition SkSLSymbol.h:51
std::string description() const override
Variable * var() const
const uint8_t uint32_t uint32_t GError ** error
const char * name
Definition fuchsia.cc:50
void ConvertProgram(const Program &program, const char *sampleCoords, const char *inputColor, const char *destColor, Callbacks *callbacks)
bool ToSPIRV(Program &program, const ShaderCaps *caps, OutputStream &out)
bool ToWGSL(Program &program, const ShaderCaps *caps, OutputStream &out)
bool ToGLSL(Program &program, const ShaderCaps *caps, OutputStream &out)
bool ToMetal(Program &program, const ShaderCaps *caps, OutputStream &out)
bool ToHLSL(Program &program, const ShaderCaps *caps, OutputStream &out)
std::unique_ptr< RP::Program > MakeRasterPipelineProgram(const SkSL::Program &program, const FunctionDefinition &function, DebugTracePriv *debugTrace, bool writeTraceOps)
std::string PrettyPrint(const std::string &string)
dst
Definition cp.py:12
Definition main.py:1
const myers::Point & get(const myers::Segment &)
constexpr bool starts_with(std::string_view str, std::string_view prefix)
const FunctionDeclaration * getFunction(const char *functionName) const
static std::unique_ptr< SkWStream > as_SkWStream(SkSL::OutputStream &s)
Definition Main.cpp:53
static void show_usage()
Definition Main.cpp:492
static bool set_flag(std::optional< bool > *flag, const char *name, bool value)
Definition Main.cpp:501
static bool detect_shader_settings(const std::string &text, SkSL::ProgramSettings *settings, const SkSL::ShaderCaps **caps, std::unique_ptr< SkSL::DebugTracePriv > *debugTrace)
Definition Main.cpp:347

◆ set_flag()

static bool set_flag ( std::optional< bool > *  flag,
const char *  name,
bool  value 
)
static

Definition at line 501 of file Main.cpp.

501 {
502 if (flag->has_value()) {
503 printf("%s flag was specified multiple times\n", name);
504 return false;
505 }
506 *flag = value;
507 return true;
508}
FlutterSemanticsFlag flag
uint8_t value

◆ show_usage()

static void show_usage ( )
static

Displays a usage banner; used when the command line arguments don't make sense.

Definition at line 492 of file Main.cpp.

492 {
493 printf("usage: skslc <input> <output> <flags>\n"
494 " skslc <worklist>\n"
495 "\n"
496 "Allowed flags:\n"
497 "--settings: honor embedded /*#pragma settings*/ comments.\n"
498 "--nosettings: ignore /*#pragma settings*/ comments\n");
499}

◆ SkDebugf()

void SkDebugf ( const char  format[],
  ... 
)

Definition at line 42 of file Main.cpp.

42 {
43 va_list args;
45 vfprintf(stderr, format, args);
46 va_end(args);
47}
uint32_t uint32_t * format
va_start(args, format)
va_end(args)