25#include <forward_list>
47 size_t slashPos =
path.find_last_of(
"/\\");
48 return path.substr(slashPos == std::string::npos ? 0 : slashPos + 1);
52 size_t dotPos =
path.find_last_of(
'.');
53 return path.substr(0, dotPos);
60 printf(
"usage: sksl-minify <output> <input> [--frag|--vert|--compute|--shader|"
61 "--colorfilter|--blender|--meshfrag|--meshvert] [dependencies...]\n");
69 return std::isalnum(c) || c ==
'$' || c ==
'_';
73 return c ==
'+' || c ==
'-';
78 std::forward_list<std::unique_ptr<const SkSL::Module>>
modules;
86 if (paths.
size() == 1) {
88 std::string defaultRuntimeShaderPaths[] = {
97 paths = paths.
first(1);
106 for (
auto modulePath = paths.
rbegin(); modulePath != paths.
rend(); ++modulePath) {
107 std::ifstream in(*modulePath);
108 std::string moduleSource{std::istreambuf_iterator<char>(in),
109 std::istreambuf_iterator<char>()};
111 printf(
"error reading '%s'\n", modulePath->c_str());
117 std::unique_ptr<SkSL::Module>
m =
compiler.compileModule(kind,
119 std::move(moduleSource),
138 std::string_view
text,
146 std::string_view lastTokenText =
" ";
149 token = lexer.
next();
150 if (token.
fKind == TokenKind::TK_END_OF_FILE) {
153 if (token.
fKind == TokenKind::TK_LINE_COMMENT ||
154 token.
fKind == TokenKind::TK_BLOCK_COMMENT ||
155 token.
fKind == TokenKind::TK_WHITESPACE) {
159 if (token.
fKind == TokenKind::TK_INVALID) {
160 printf(
"%.*s: unable to parse '%.*s' at offset %d\n",
161 (
int)inputPath.size(), inputPath.data(),
162 (
int)thisTokenText.size(), thisTokenText.data(),
166 if (thisTokenText.empty()) {
169 if (token.
fKind == TokenKind::TK_FLOAT_LITERAL) {
172 while (thisTokenText.back() ==
'0' && thisTokenText.size() >= 3) {
173 thisTokenText.remove_suffix(1);
178 thisTokenText.remove_prefix(1);
184 out.writeText(
"\"\n\"");
189 bool adjacentIdentifiers =
194 bool adjacentPlusOrMinus =
198 if (adjacentIdentifiers || adjacentPlusOrMinus) {
202 out.write(thisTokenText.data(), thisTokenText.size());
203 lineWidth += thisTokenText.size();
204 lastTokenText = thisTokenText;
211 size_t startingCount =
args->size();
212 auto iter = std::remove_if(
args->begin(),
args->end(),
213 [&](
const std::string&
a) { return a == flagName; });
215 return args->size() < startingCount;
241 isBlender, isMeshFrag, isMeshVert})) {
249 }
else if (isCompute) {
251 }
else if (isColorFilter) {
253 }
else if (isBlender) {
255 }
else if (isMeshFrag) {
257 }
else if (isMeshVert) {
259 }
else if (isPrivateShader) {
267 if (
args.size() < 2) {
271 const std::string& outputPath =
args[0];
275 std::forward_list<std::unique_ptr<const SkSL::Module>>
modules =
284 if (!
out.isValid()) {
285 printf(
"error writing '%s'\n", outputPath.c_str());
291 out.printf(
"static constexpr char SKSL_MINIFIED_%s[] =\n\"", baseName.c_str());
296 for (
const std::unique_ptr<SkSL::ProgramElement>& element : module->
fElements) {
299 if (
name ==
"Attributes" ||
name ==
"Varyings") {
305 text += element->description();
314 out.writeText(
"\";");
319 printf(
"error writing '%s'\n", outputPath.c_str());
333 std::vector<std::string>
args;
334 for (
int index=0; index<argc; ++index) {
ResultCode ProcessWorklist(const char *worklistPath, const std::function< ResultCode(SkSpan< std::string > args)> &processCommandFn)
std::string SkGetExecutablePath()
int main(int argc, const char **argv)
static std::string base_name(const std::string &path)
static ResultCode process_command(SkSpan< std::string > args)
static bool find_boolean_flag(SkSpan< std::string > *args, std::string_view flagName)
void SkDebugf(const char format[],...)
static std::string_view stringize(const SkSL::Token &token, std::string_view text)
static std::forward_list< std::unique_ptr< const SkSL::Module > > compile_module_list(SkSpan< const std::string > paths, SkSL::ProgramKind kind)
static bool maybe_identifier(char c)
static std::string remove_extension(const std::string &path)
static bool generate_minified_text(std::string_view inputPath, std::string_view text, SkSL::FileOutputStream &out)
static SkSL::ProgramKind gProgramKind
static bool is_plus_or_minus(char c)
static bool has_overlapping_flags(SkSpan< const bool > flags)
static constexpr char SEPARATOR
static SkString Dirname(const char *fullPath)
void start(std::string_view text)
const Module * rootModule()
void addPublicTypeAliases(const SkSL::Module *module)
static ModuleLoader Get()
constexpr SkSpan< T > first(size_t prefixLen) const
constexpr T & front() const
constexpr SkSpan< T > subspan(size_t offset) const
constexpr auto rbegin() const
constexpr auto rend() const
constexpr size_t size() const
const char * c_str() const
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint32_t uint32_t * format
size_t raster_pipeline_highp_stride
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
DEF_SWITCHES_START aot vmservice shared library name
constexpr bool starts_with(std::string_view str, std::string_view prefix)
constexpr bool contains(std::string_view str, std::string_view needle)
std::vector< std::unique_ptr< ProgramElement > > fElements
static bool IsRuntimeEffect(ProgramKind kind)