Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkSLReturnsInputAlpha.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023 Google LLC
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
30
31#include <memory>
32
33using namespace skia_private;
34
35namespace SkSL {
36namespace {
37
38class ReturnsInputAlphaVisitor : public ProgramVisitor {
39public:
40 ReturnsInputAlphaVisitor(const ProgramUsage& u) : fUsage(u) {}
41
42 bool visitProgramElement(const ProgramElement& pe) override {
43 const FunctionDeclaration& decl = pe.as<FunctionDefinition>().declaration();
44 SkSpan<Variable* const> parameters = decl.parameters();
45
46 // We expect a color filter to have a single half4 input.
47 if (parameters.size() != 1 ||
48 parameters[0]->type().columns() != 4 ||
49 !parameters[0]->type().componentType().isFloat()) {
50 // This doesn't look like a color filter.
51 return true;
52 }
53 fInputVar = parameters[0];
54
55 // If the input variable has been written-to, then returning `input.a` isn't sufficient to
56 // guarantee that alpha is preserved.
57 ProgramUsage::VariableCounts counts = fUsage.get(*fInputVar);
58 if (counts.fWrite != 0) {
59 return true;
60 }
61
63 }
64
65 bool isInputVar(const Expression& expr) {
66 return expr.is<VariableReference>() && expr.as<VariableReference>().variable() == fInputVar;
67 }
68
69 bool isInputSwizzleEndingWithAlpha(const Expression& expr) {
70 if (!expr.is<Swizzle>()) {
71 return false;
72 }
73 const Swizzle& swizzle = expr.as<Swizzle>();
74 return this->isInputVar(*swizzle.base()) && swizzle.components().back() == 3;
75 }
76
77 bool returnsInputAlpha(const Expression& expr) {
78 if (this->isInputVar(expr)) {
79 // This expression returns the input value as-is.
80 return true;
81 }
82 if (expr.is<Swizzle>()) {
83 // It's a swizzle: check for `input.___a`.
84 return this->isInputSwizzleEndingWithAlpha(expr);
85 }
86 if (expr.is<ConstructorSplat>() || expr.is<ConstructorCompound>()) {
87 // This is a splat or compound constructor; check for `input.a` as its final component.
88 const AnyConstructor& ctor = expr.asAnyConstructor();
89 return this->returnsInputAlpha(*ctor.argumentSpan().back());
90 }
91 if (expr.is<ConstructorCompoundCast>()) {
92 // Ignore typecasts between float and half.
93 const Expression& arg = *expr.as<ConstructorCompoundCast>().argument();
94 return arg.type().componentType().isFloat() && this->returnsInputAlpha(arg);
95 }
96 if (expr.is<TernaryExpression>()) {
97 // Both sides of the ternary must preserve input alpha.
98 const TernaryExpression& ternary = expr.as<TernaryExpression>();
99 return this->returnsInputAlpha(*ternary.ifTrue()) &&
100 this->returnsInputAlpha(*ternary.ifFalse());
101 }
102 // We weren't able to pattern-match here.
103 return false;
104 }
105
106 bool visitStatement(const Statement& s) override {
107 if (s.is<ReturnStatement>()) {
108 return !this->returnsInputAlpha(*s.as<ReturnStatement>().expression());
109 }
111 }
112
113 bool visitExpression(const Expression& e) override {
114 // No need to recurse into expressions; these can never contain return statements.
115 return false;
116 }
117
118private:
119 const ProgramUsage& fUsage;
120 const Variable* fInputVar = nullptr;
121
122 using INHERITED = ProgramVisitor;
123};
124
125} // namespace
126
128 ReturnsInputAlphaVisitor visitor{usage};
129 return !visitor.visitProgramElement(function);
130}
131
132} // namespace SkSL
#define INHERITED(method,...)
virtual bool visitStatement(typename T::Statement &statement)
virtual bool visitProgramElement(typename T::ProgramElement &programElement)
constexpr size_t size() const
Definition SkSpan_impl.h:95
struct MyStruct s
Dart_NativeFunction function
Definition fuchsia.cc:51
bool ReturnsInputAlpha(const FunctionDefinition &function, const ProgramUsage &usage)
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 counts
Definition switches.h:239
static void usage(char *argv0)