1 /*
2 * Copyright 2021 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 "include/sksl/DSLStatement.h"
9
10 #include "include/sksl/DSLBlock.h"
11 #include "include/sksl/DSLExpression.h"
12 #include "src/sksl/SkSLCompiler.h"
13 #include "src/sksl/SkSLThreadContext.h"
14 #include "src/sksl/ir/SkSLBlock.h"
15 #include "src/sksl/ir/SkSLExpressionStatement.h"
16 #include "src/sksl/ir/SkSLNop.h"
17
18 #if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
19 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
20 #endif
21
22 namespace SkSL {
23
24 namespace dsl {
25
DSLStatement()26 DSLStatement::DSLStatement() {}
27
DSLStatement(DSLBlock block)28 DSLStatement::DSLStatement(DSLBlock block)
29 : fStatement(block.release()) {}
30
DSLStatement(DSLExpression expr)31 DSLStatement::DSLStatement(DSLExpression expr) {
32 std::unique_ptr<SkSL::Expression> skslExpr = expr.release();
33 if (skslExpr) {
34 fStatement = SkSL::ExpressionStatement::Make(ThreadContext::Context(), std::move(skslExpr));
35 }
36 }
37
DSLStatement(std::unique_ptr<SkSL::Expression> expr)38 DSLStatement::DSLStatement(std::unique_ptr<SkSL::Expression> expr)
39 : fStatement(SkSL::ExpressionStatement::Make(ThreadContext::Context(), std::move(expr))) {
40 SkASSERT(this->hasValue());
41 }
42
DSLStatement(std::unique_ptr<SkSL::Statement> stmt)43 DSLStatement::DSLStatement(std::unique_ptr<SkSL::Statement> stmt)
44 : fStatement(std::move(stmt)) {
45 SkASSERT(this->hasValue());
46 }
47
DSLStatement(DSLPossibleExpression expr,PositionInfo pos)48 DSLStatement::DSLStatement(DSLPossibleExpression expr, PositionInfo pos)
49 : DSLStatement(DSLExpression(std::move(expr), pos)) {}
50
DSLStatement(DSLPossibleStatement stmt,PositionInfo pos)51 DSLStatement::DSLStatement(DSLPossibleStatement stmt, PositionInfo pos) {
52 ThreadContext::ReportErrors(pos);
53 if (stmt.hasValue()) {
54 fStatement = std::move(stmt.fStatement);
55 } else {
56 fStatement = SkSL::Nop::Make();
57 }
58 if (pos.line() != -1) {
59 fStatement->fLine = pos.line();
60 }
61 }
62
~DSLStatement()63 DSLStatement::~DSLStatement() {
64 #if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
65 if (fStatement && ThreadContext::InFragmentProcessor()) {
66 ThreadContext::CurrentEmitArgs()->fFragBuilder->codeAppend(this->release());
67 return;
68 }
69 #endif
70 SkASSERTF(!fStatement || !ThreadContext::Settings().fAssertDSLObjectsReleased,
71 "Statement destroyed without being incorporated into program (see "
72 "ProgramSettings::fAssertDSLObjectsReleased)");
73 }
74
DSLPossibleStatement(std::unique_ptr<SkSL::Statement> statement)75 DSLPossibleStatement::DSLPossibleStatement(std::unique_ptr<SkSL::Statement> statement)
76 : fStatement(std::move(statement)) {}
77
~DSLPossibleStatement()78 DSLPossibleStatement::~DSLPossibleStatement() {
79 if (fStatement) {
80 // this handles incorporating the expression into the output tree
81 DSLStatement(std::move(fStatement));
82 }
83 }
84
operator ,(DSLStatement left,DSLStatement right)85 DSLStatement operator,(DSLStatement left, DSLStatement right) {
86 int line = left.fStatement->fLine;
87 StatementArray stmts;
88 stmts.reserve_back(2);
89 stmts.push_back(left.release());
90 stmts.push_back(right.release());
91 return DSLStatement(SkSL::Block::MakeUnscoped(line, std::move(stmts)));
92 }
93
94 } // namespace dsl
95
96 } // namespace SkSL
97