Coverage Report

Created: 2024-09-14 07:19

/src/skia/src/sksl/transform/SkSLReplaceSplatCastsWithSwizzles.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2024 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
8
#include "src/sksl/SkSLModule.h"
9
#include "src/sksl/ir/SkSLConstructorSplat.h"
10
#include "src/sksl/ir/SkSLExpression.h"
11
#include "src/sksl/ir/SkSLFunctionDefinition.h"
12
#include "src/sksl/ir/SkSLLiteral.h"
13
#include "src/sksl/ir/SkSLProgramElement.h"
14
#include "src/sksl/ir/SkSLSwizzle.h"
15
#include "src/sksl/ir/SkSLType.h"
16
#include "src/sksl/transform/SkSLProgramWriter.h"
17
#include "src/sksl/transform/SkSLTransform.h"
18
19
#include <memory>
20
#include <utility>
21
#include <vector>
22
23
namespace SkSL {
24
25
class Context;
26
27
0
void Transform::ReplaceSplatCastsWithSwizzles(const Context& context, Module& module) {
28
0
    class SwizzleWriter : public ProgramWriter {
29
0
    public:
30
0
        SwizzleWriter(const Context& ctx) : fContext(ctx) {}
31
32
0
        bool visitExpressionPtr(std::unique_ptr<Expression>& expr) override {
33
0
            if (INHERITED::visitExpressionPtr(expr)) {
34
0
                return true;
35
0
            }
36
0
            if (expr->is<ConstructorSplat>()) {
37
                // If the argument is a literal, only allow floats. The swizzled-literal syntax only
38
                // works properly for floats.
39
0
                std::unique_ptr<Expression>& arg = expr->as<ConstructorSplat>().argument();
40
0
                if (!arg->is<Literal>() || (arg->type().isFloat() && arg->type().highPrecision())) {
41
                    // Synthesize a splat like `.xxxx`, matching the column count of the splat.
42
0
                    ComponentArray components;
43
0
                    components.push_back_n(expr->type().columns(), SwizzleComponent::X);
44
45
                    // Replace the splat expression with the swizzle.
46
0
                    expr = Swizzle::MakeExact(fContext, expr->position(), std::move(arg),
47
0
                                              std::move(components));
48
0
                }
49
0
            }
50
0
            return false;
51
0
        }
52
53
0
        const Context& fContext;
54
55
0
        using INHERITED = ProgramWriter;
56
0
    };
57
58
0
    for (std::unique_ptr<ProgramElement>& pe : module.fElements) {
59
0
        if (pe->is<FunctionDefinition>()) {
60
0
            SwizzleWriter writer{context};
61
0
            writer.visitStatementPtr(pe->as<FunctionDefinition>().body());
62
0
        }
63
0
    }
64
0
}
65
66
}  // namespace SkSL