Fixed SkSL optimization issue
When collapsing static switches down to a single statement, we detect break statements and don't copy them. But the logic was broken; we weren't copying the entire statement in which the break occurred, which could be a block, causing some of the code to simply be omitted. Change-Id: Ic5b59c11d12326c93d49080193a0a5297732bfb0 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/295776 Commit-Queue: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: John Stiles <johnstiles@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
ee2ffc3b43
commit
739e1caf35
@ -1070,6 +1070,21 @@ static bool contains_unconditional_break(Statement& s) {
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_all_but_break(std::unique_ptr<Statement>& stmt,
|
||||
std::vector<std::unique_ptr<Statement>*>* target) {
|
||||
switch (stmt->fKind) {
|
||||
case Statement::kBlock_Kind:
|
||||
for (auto& s : ((Block&) *stmt).fStatements) {
|
||||
copy_all_but_break(s, target);
|
||||
}
|
||||
break;
|
||||
case Statement::kBreak_Kind:
|
||||
return;
|
||||
default:
|
||||
target->push_back(&stmt);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a block containing all of the statements that will be run if the given case matches
|
||||
// (which, owing to the statements being owned by unique_ptrs, means the switch itself will be
|
||||
// broken by this call and must then be discarded).
|
||||
@ -1089,6 +1104,7 @@ static std::unique_ptr<Statement> block_for_case(SwitchStatement* s, SwitchCase*
|
||||
}
|
||||
if (contains_unconditional_break(*stmt)) {
|
||||
capturing = false;
|
||||
copy_all_but_break(stmt, &statementPtrs);
|
||||
break;
|
||||
}
|
||||
statementPtrs.push_back(&stmt);
|
||||
|
@ -1635,6 +1635,75 @@ DEF_TEST(SkSLSwitch, r) {
|
||||
" }\n"
|
||||
" sk_FragColor = vec4(x);\n"
|
||||
"}\n");
|
||||
// static test w/ break in a block
|
||||
test(r,
|
||||
"void main() {"
|
||||
" float x = 0.0;"
|
||||
" switch (0) {"
|
||||
" case 0: {"
|
||||
" x = 0.0;"
|
||||
" sk_FragColor = half4(half(x));"
|
||||
" break;"
|
||||
" }"
|
||||
" case 1:"
|
||||
" x = 1.0;"
|
||||
" }"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"void main() {\n"
|
||||
" {\n"
|
||||
" sk_FragColor = vec4(0.0);\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
// static test w/ static conditional break in a block
|
||||
test(r,
|
||||
"void main() {"
|
||||
" float x = 0.0;"
|
||||
" switch (0) {"
|
||||
" case 0:"
|
||||
" x = 0.0;"
|
||||
" if (x < 1) { sk_FragColor = half4(half(x)); break; }"
|
||||
" case 1:"
|
||||
" x = 1.0;"
|
||||
" }"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"void main() {\n"
|
||||
" {\n"
|
||||
" sk_FragColor = vec4(0.0);\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
// static test w/ non-static conditional break in a block
|
||||
test(r,
|
||||
"void main() {"
|
||||
" float x = 0.0;"
|
||||
" switch (0) {"
|
||||
" case 0:"
|
||||
" x = 0.0;"
|
||||
" if (x < sqrt(1)) { sk_FragColor = half4(half(x)); break; }"
|
||||
" case 1:"
|
||||
" x = 1.0;"
|
||||
" }"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"void main() {\n"
|
||||
" switch (0) {\n"
|
||||
" case 0:\n"
|
||||
" ;\n"
|
||||
" if (0.0 < sqrt(1.0)) {\n"
|
||||
" sk_FragColor = vec4(0.0);\n"
|
||||
" break;\n"
|
||||
" }\n"
|
||||
" case 1:\n"
|
||||
" ;\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLRectangleTexture, r) {
|
||||
|
Loading…
Reference in New Issue
Block a user