re-land of switched skslc from std::string to SkString
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=5084 Change-Id: Ib21c30afc0d8483392b417e660b7fecfcc30e617 Reviewed-on: https://skia-review.googlesource.com/5084 Reviewed-by: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
e54d4cefb7
commit
9e1138d566
@ -14,7 +14,6 @@
|
||||
#include "gl/builders/GrGLShaderStringBuilder.h"
|
||||
#include "SkSLCompiler.h"
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
const GrGLContext* GLBench::getGLContext(SkCanvas* canvas) {
|
||||
// This bench exclusively tests GL calls directly
|
||||
@ -66,11 +65,11 @@ void GLBench::onDraw(int loops, SkCanvas* canvas) {
|
||||
|
||||
GrGLuint GLBench::CompileShader(const GrGLContext* context, const char* sksl, GrGLenum type) {
|
||||
const GrGLInterface* gl = context->interface();
|
||||
std::string glsl;
|
||||
SkString glsl;
|
||||
bool result = context->compiler()->toGLSL(type == GR_GL_VERTEX_SHADER
|
||||
? SkSL::Program::kVertex_Kind
|
||||
: SkSL::Program::kFragment_Kind,
|
||||
std::string(sksl),
|
||||
SkString(sksl),
|
||||
*context->caps()->glslCaps(),
|
||||
&glsl);
|
||||
if (!result) {
|
||||
|
@ -402,9 +402,9 @@ int fuzz_color_deserialize(sk_sp<SkData> bytes) {
|
||||
#if SK_SUPPORT_GPU
|
||||
int fuzz_sksl2glsl(sk_sp<SkData> bytes) {
|
||||
SkSL::Compiler compiler;
|
||||
std::string output;
|
||||
SkString output;
|
||||
bool result = compiler.toGLSL(SkSL::Program::kFragment_Kind,
|
||||
(const char*)bytes->data(), *SkSL::GLSLCapsFactory::Default(), &output);
|
||||
SkString((const char*)bytes->data()), *SkSL::GLSLCapsFactory::Default(), &output);
|
||||
|
||||
if (!result) {
|
||||
SkDebugf("[terminated] Couldn't compile input.\n");
|
||||
|
16
gyp/sksl.gyp
16
gyp/sksl.gyp
@ -10,13 +10,15 @@
|
||||
'standalone_static_library': 1,
|
||||
'sources': [ '<!@(python read_gni.py ../gn/sksl.gni skia_sksl_sources)' ],
|
||||
'include_dirs': [
|
||||
'../include/config',
|
||||
'../include/core',
|
||||
'../include/gpu',
|
||||
'../include/private',
|
||||
'../include/utils',
|
||||
'../src/gpu',
|
||||
'../src/sksl',
|
||||
'../include/config',
|
||||
'../include/core',
|
||||
'../include/gpu',
|
||||
'../include/private',
|
||||
'../include/utils',
|
||||
'../src/core',
|
||||
'../src/gpu',
|
||||
'../src/sksl',
|
||||
'../src/utils',
|
||||
],
|
||||
'defines': [
|
||||
'SKIA'
|
||||
|
@ -11,13 +11,14 @@
|
||||
'target_name': 'skslc',
|
||||
'type': 'executable',
|
||||
'include_dirs': [
|
||||
'../include/config',
|
||||
'../include/core',
|
||||
'../include/gpu',
|
||||
'../include/private',
|
||||
'../include/utils',
|
||||
'../src/gpu',
|
||||
'../src/sksl',
|
||||
'../include/config',
|
||||
'../include/core',
|
||||
'../include/gpu',
|
||||
'../include/private',
|
||||
'../include/utils',
|
||||
'../src/core',
|
||||
'../src/gpu',
|
||||
'../src/utils',
|
||||
],
|
||||
'sources': [
|
||||
'<!@(python read_gni.py ../gn/sksl.gni skia_sksl_sources)',
|
||||
|
@ -21,18 +21,19 @@ static const bool c_PrintShaders{false};
|
||||
|
||||
static void print_shader_source(const char** strings, int* lengths, int count);
|
||||
|
||||
static void dump_string(std::string s) {
|
||||
static void dump_string(SkString s) {
|
||||
// on Android, SkDebugf only displays the first 1K characters of output, which results in
|
||||
// incomplete shader source code. Print each line individually to avoid this problem.
|
||||
size_t index = 0;
|
||||
const char* chars = s.c_str();
|
||||
for (;;) {
|
||||
size_t next = s.find("\n", index);
|
||||
if (next == std::string::npos) {
|
||||
SkDebugf("%s", s.substr(index).c_str());
|
||||
break;
|
||||
const char* next = strchr(chars, '\n');
|
||||
if (next) {
|
||||
next++;
|
||||
SkDebugf("%s", SkString(chars, next - chars).c_str());
|
||||
chars = next;
|
||||
} else {
|
||||
SkDebugf("%s", s.substr(index, next - index + 1).c_str());
|
||||
index = next + 1;
|
||||
SkDebugf("%s", chars);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -52,23 +53,22 @@ GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string sksl;
|
||||
SkString sksl;
|
||||
#ifdef SK_DEBUG
|
||||
SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths, count, false);
|
||||
sksl = std::string(prettySource.c_str());
|
||||
sksl = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths, count, false);
|
||||
#else
|
||||
for (int i = 0; i < count; i++) {
|
||||
sksl.append(strings[i], lengths[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string glsl;
|
||||
SkString glsl;
|
||||
SkSL::Compiler& compiler = *glCtx.compiler();
|
||||
SkASSERT(type == GR_GL_VERTEX_SHADER || type == GR_GL_FRAGMENT_SHADER);
|
||||
SkDEBUGCODE(bool result = )compiler.toGLSL(type == GR_GL_VERTEX_SHADER
|
||||
? SkSL::Program::kVertex_Kind
|
||||
: SkSL::Program::kFragment_Kind,
|
||||
std::string(sksl.c_str()),
|
||||
sksl,
|
||||
*glCtx.caps()->glslCaps(),
|
||||
&glsl);
|
||||
#ifdef SK_DEBUG
|
||||
@ -82,7 +82,7 @@ GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
|
||||
#endif
|
||||
|
||||
const char* glslChars = glsl.c_str();
|
||||
GrGLint glslLength = (GrGLint) glsl.length();
|
||||
GrGLint glslLength = (GrGLint) glsl.size();
|
||||
GR_GL_CALL(gli, ShaderSource(shaderId, 1, &glslChars, &glslLength));
|
||||
|
||||
// If tracing is enabled in chrome then we pretty print
|
||||
|
@ -292,7 +292,7 @@ bool GrCompileVkShaderModule(const GrVkGpu* gpu,
|
||||
moduleCreateInfo.flags = 0;
|
||||
|
||||
#if USE_SKSL
|
||||
std::string code;
|
||||
SkString code;
|
||||
#else
|
||||
shaderc_compilation_result_t result = nullptr;
|
||||
#endif
|
||||
@ -304,7 +304,7 @@ bool GrCompileVkShaderModule(const GrVkGpu* gpu,
|
||||
|
||||
#if USE_SKSL
|
||||
bool result = gpu->shaderCompiler()->toSPIRV(vk_shader_stage_to_skiasl_kind(stage),
|
||||
std::string(shaderString),
|
||||
SkString(shaderString),
|
||||
&code);
|
||||
if (!result) {
|
||||
SkDebugf("%s\n", gpu->shaderCompiler()->errorText().c_str());
|
||||
|
@ -9,8 +9,6 @@
|
||||
#define SKSL_CODEGENERATOR
|
||||
|
||||
#include "ir/SkSLProgram.h"
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
@ -22,7 +20,7 @@ class CodeGenerator {
|
||||
public:
|
||||
virtual ~CodeGenerator() {}
|
||||
|
||||
virtual void generateCode(const Program& program, std::ostream& out) = 0;
|
||||
virtual void generateCode(const Program& program, SkWStream& out) = 0;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -7,9 +7,6 @@
|
||||
|
||||
#include "SkSLCompiler.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <streambuf>
|
||||
|
||||
#include "ast/SkSLASTPrecision.h"
|
||||
#include "SkSLCFGGenerator.h"
|
||||
#include "SkSLIRGenerator.h"
|
||||
@ -71,17 +68,17 @@ Compiler::Compiler()
|
||||
ADD_TYPE(BVec3);
|
||||
ADD_TYPE(BVec4);
|
||||
ADD_TYPE(Mat2x2);
|
||||
types->addWithoutOwnership("mat2x2", fContext.fMat2x2_Type.get());
|
||||
types->addWithoutOwnership(SkString("mat2x2"), fContext.fMat2x2_Type.get());
|
||||
ADD_TYPE(Mat2x3);
|
||||
ADD_TYPE(Mat2x4);
|
||||
ADD_TYPE(Mat3x2);
|
||||
ADD_TYPE(Mat3x3);
|
||||
types->addWithoutOwnership("mat3x3", fContext.fMat3x3_Type.get());
|
||||
types->addWithoutOwnership(SkString("mat3x3"), fContext.fMat3x3_Type.get());
|
||||
ADD_TYPE(Mat3x4);
|
||||
ADD_TYPE(Mat4x2);
|
||||
ADD_TYPE(Mat4x3);
|
||||
ADD_TYPE(Mat4x4);
|
||||
types->addWithoutOwnership("mat4x4", fContext.fMat4x4_Type.get());
|
||||
types->addWithoutOwnership(SkString("mat4x4"), fContext.fMat4x4_Type.get());
|
||||
ADD_TYPE(GenType);
|
||||
ADD_TYPE(GenDType);
|
||||
ADD_TYPE(GenIType);
|
||||
@ -140,7 +137,7 @@ Compiler::Compiler()
|
||||
|
||||
Modifiers::Flag ignored1;
|
||||
std::vector<std::unique_ptr<ProgramElement>> ignored2;
|
||||
this->internalConvertProgram(SKSL_INCLUDE, &ignored1, &ignored2);
|
||||
this->internalConvertProgram(SkString(SKSL_INCLUDE), &ignored1, &ignored2);
|
||||
fIRGenerator->fSymbolTable->markAllFunctionsBuiltin();
|
||||
ASSERT(!fErrorCount);
|
||||
}
|
||||
@ -289,7 +286,7 @@ void Compiler::scanCFG(const FunctionDefinition& f) {
|
||||
for (size_t i = 0; i < cfg.fBlocks.size(); i++) {
|
||||
if (i != cfg.fStart && !cfg.fBlocks[i].fEntrances.size() &&
|
||||
cfg.fBlocks[i].fNodes.size()) {
|
||||
this->error(cfg.fBlocks[i].fNodes[0].fNode->fPosition, "unreachable");
|
||||
this->error(cfg.fBlocks[i].fNodes[0].fNode->fPosition, SkString("unreachable"));
|
||||
}
|
||||
}
|
||||
if (fErrorCount) {
|
||||
@ -318,12 +315,12 @@ void Compiler::scanCFG(const FunctionDefinition& f) {
|
||||
// check for missing return
|
||||
if (f.fDeclaration.fReturnType != *fContext.fVoid_Type) {
|
||||
if (cfg.fBlocks[cfg.fExit].fEntrances.size()) {
|
||||
this->error(f.fPosition, "function can exit without returning a value");
|
||||
this->error(f.fPosition, SkString("function can exit without returning a value"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::internalConvertProgram(std::string text,
|
||||
void Compiler::internalConvertProgram(SkString text,
|
||||
Modifiers::Flag* defaultPrecision,
|
||||
std::vector<std::unique_ptr<ProgramElement>>* result) {
|
||||
Parser parser(text, *fTypes, *this);
|
||||
@ -386,7 +383,7 @@ void Compiler::internalConvertProgram(std::string text,
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, std::string text) {
|
||||
std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, SkString text) {
|
||||
fErrorText = "";
|
||||
fErrorCount = 0;
|
||||
fIRGenerator->pushSymbolTable();
|
||||
@ -394,10 +391,10 @@ std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, std::strin
|
||||
Modifiers::Flag ignored;
|
||||
switch (kind) {
|
||||
case Program::kVertex_Kind:
|
||||
this->internalConvertProgram(SKSL_VERT_INCLUDE, &ignored, &elements);
|
||||
this->internalConvertProgram(SkString(SKSL_VERT_INCLUDE), &ignored, &elements);
|
||||
break;
|
||||
case Program::kFragment_Kind:
|
||||
this->internalConvertProgram(SKSL_FRAG_INCLUDE, &ignored, &elements);
|
||||
this->internalConvertProgram(SkString(SKSL_FRAG_INCLUDE), &ignored, &elements);
|
||||
break;
|
||||
}
|
||||
fIRGenerator->fSymbolTable->markAllFunctionsBuiltin();
|
||||
@ -410,13 +407,13 @@ std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, std::strin
|
||||
return result;
|
||||
}
|
||||
|
||||
void Compiler::error(Position position, std::string msg) {
|
||||
void Compiler::error(Position position, SkString msg) {
|
||||
fErrorCount++;
|
||||
fErrorText += "error: " + position.description() + ": " + msg.c_str() + "\n";
|
||||
}
|
||||
|
||||
std::string Compiler::errorText() {
|
||||
std::string result = fErrorText;
|
||||
SkString Compiler::errorText() {
|
||||
SkString result = fErrorText;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -430,42 +427,42 @@ void Compiler::writeErrorCount() {
|
||||
}
|
||||
}
|
||||
|
||||
bool Compiler::toSPIRV(Program::Kind kind, const std::string& text, std::ostream& out) {
|
||||
bool Compiler::toSPIRV(Program::Kind kind, const SkString& text, SkWStream& out) {
|
||||
auto program = this->convertProgram(kind, text);
|
||||
if (fErrorCount == 0) {
|
||||
SkSL::SPIRVCodeGenerator cg(&fContext);
|
||||
cg.generateCode(*program.get(), out);
|
||||
ASSERT(!out.rdstate());
|
||||
}
|
||||
return fErrorCount == 0;
|
||||
}
|
||||
|
||||
bool Compiler::toSPIRV(Program::Kind kind, const std::string& text, std::string* out) {
|
||||
std::stringstream buffer;
|
||||
bool Compiler::toSPIRV(Program::Kind kind, const SkString& text, SkString* out) {
|
||||
SkDynamicMemoryWStream buffer;
|
||||
bool result = this->toSPIRV(kind, text, buffer);
|
||||
if (result) {
|
||||
*out = buffer.str();
|
||||
sk_sp<SkData> data(buffer.detachAsData());
|
||||
*out = SkString((const char*) data->data(), data->size());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Compiler::toGLSL(Program::Kind kind, const std::string& text, const GrGLSLCaps& caps,
|
||||
std::ostream& out) {
|
||||
bool Compiler::toGLSL(Program::Kind kind, const SkString& text, const GrGLSLCaps& caps,
|
||||
SkWStream& out) {
|
||||
auto program = this->convertProgram(kind, text);
|
||||
if (fErrorCount == 0) {
|
||||
SkSL::GLSLCodeGenerator cg(&fContext, &caps);
|
||||
cg.generateCode(*program.get(), out);
|
||||
ASSERT(!out.rdstate());
|
||||
}
|
||||
return fErrorCount == 0;
|
||||
}
|
||||
|
||||
bool Compiler::toGLSL(Program::Kind kind, const std::string& text, const GrGLSLCaps& caps,
|
||||
std::string* out) {
|
||||
std::stringstream buffer;
|
||||
bool Compiler::toGLSL(Program::Kind kind, const SkString& text, const GrGLSLCaps& caps,
|
||||
SkString* out) {
|
||||
SkDynamicMemoryWStream buffer;
|
||||
bool result = this->toGLSL(kind, text, caps, buffer);
|
||||
if (result) {
|
||||
*out = buffer.str();
|
||||
sk_sp<SkData> data(buffer.detachAsData());
|
||||
*out = SkString((const char*) data->data(), data->size());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -37,21 +37,21 @@ public:
|
||||
|
||||
~Compiler();
|
||||
|
||||
std::unique_ptr<Program> convertProgram(Program::Kind kind, std::string text);
|
||||
std::unique_ptr<Program> convertProgram(Program::Kind kind, SkString text);
|
||||
|
||||
bool toSPIRV(Program::Kind kind, const std::string& text, std::ostream& out);
|
||||
bool toSPIRV(Program::Kind kind, const SkString& text, SkWStream& out);
|
||||
|
||||
bool toSPIRV(Program::Kind kind, const std::string& text, std::string* out);
|
||||
bool toSPIRV(Program::Kind kind, const SkString& text, SkString* out);
|
||||
|
||||
bool toGLSL(Program::Kind kind, const std::string& text, const GrGLSLCaps& caps,
|
||||
std::ostream& out);
|
||||
bool toGLSL(Program::Kind kind, const SkString& text, const GrGLSLCaps& caps,
|
||||
SkWStream& out);
|
||||
|
||||
bool toGLSL(Program::Kind kind, const std::string& text, const GrGLSLCaps& caps,
|
||||
std::string* out);
|
||||
bool toGLSL(Program::Kind kind, const SkString& text, const GrGLSLCaps& caps,
|
||||
SkString* out);
|
||||
|
||||
void error(Position position, std::string msg) override;
|
||||
void error(Position position, SkString msg) override;
|
||||
|
||||
std::string errorText();
|
||||
SkString errorText();
|
||||
|
||||
void writeErrorCount();
|
||||
|
||||
@ -66,17 +66,17 @@ private:
|
||||
|
||||
void scanCFG(const FunctionDefinition& f);
|
||||
|
||||
void internalConvertProgram(std::string text,
|
||||
void internalConvertProgram(SkString text,
|
||||
Modifiers::Flag* defaultPrecision,
|
||||
std::vector<std::unique_ptr<ProgramElement>>* result);
|
||||
|
||||
std::shared_ptr<SymbolTable> fTypes;
|
||||
IRGenerator* fIRGenerator;
|
||||
std::string fSkiaVertText; // FIXME store parsed version instead
|
||||
SkString fSkiaVertText; // FIXME store parsed version instead
|
||||
|
||||
Context fContext;
|
||||
int fErrorCount;
|
||||
std::string fErrorText;
|
||||
SkString fErrorText;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -19,114 +19,120 @@ namespace SkSL {
|
||||
class Context {
|
||||
public:
|
||||
Context()
|
||||
: fInvalid_Type(new Type("<INVALID>"))
|
||||
, fVoid_Type(new Type("void"))
|
||||
, fDouble_Type(new Type("double", true))
|
||||
, fDVec2_Type(new Type("dvec2", *fDouble_Type, 2))
|
||||
, fDVec3_Type(new Type("dvec3", *fDouble_Type, 3))
|
||||
, fDVec4_Type(new Type("dvec4", *fDouble_Type, 4))
|
||||
, fFloat_Type(new Type("float", true, { fDouble_Type.get() }))
|
||||
, fVec2_Type(new Type("vec2", *fFloat_Type, 2))
|
||||
, fVec3_Type(new Type("vec3", *fFloat_Type, 3))
|
||||
, fVec4_Type(new Type("vec4", *fFloat_Type, 4))
|
||||
, fUInt_Type(new Type("uint", true, { fFloat_Type.get(), fDouble_Type.get() }))
|
||||
, fUVec2_Type(new Type("uvec2", *fUInt_Type, 2))
|
||||
, fUVec3_Type(new Type("uvec3", *fUInt_Type, 3))
|
||||
, fUVec4_Type(new Type("uvec4", *fUInt_Type, 4))
|
||||
, fInt_Type(new Type("int", true, { fUInt_Type.get(), fFloat_Type.get(), fDouble_Type.get() }))
|
||||
, fIVec2_Type(new Type("ivec2", *fInt_Type, 2))
|
||||
, fIVec3_Type(new Type("ivec3", *fInt_Type, 3))
|
||||
, fIVec4_Type(new Type("ivec4", *fInt_Type, 4))
|
||||
, fBool_Type(new Type("bool", false))
|
||||
, fBVec2_Type(new Type("bvec2", *fBool_Type, 2))
|
||||
, fBVec3_Type(new Type("bvec3", *fBool_Type, 3))
|
||||
, fBVec4_Type(new Type("bvec4", *fBool_Type, 4))
|
||||
, fMat2x2_Type(new Type("mat2", *fFloat_Type, 2, 2))
|
||||
, fMat2x3_Type(new Type("mat2x3", *fFloat_Type, 2, 3))
|
||||
, fMat2x4_Type(new Type("mat2x4", *fFloat_Type, 2, 4))
|
||||
, fMat3x2_Type(new Type("mat3x2", *fFloat_Type, 3, 2))
|
||||
, fMat3x3_Type(new Type("mat3", *fFloat_Type, 3, 3))
|
||||
, fMat3x4_Type(new Type("mat3x4", *fFloat_Type, 3, 4))
|
||||
, fMat4x2_Type(new Type("mat4x2", *fFloat_Type, 4, 2))
|
||||
, fMat4x3_Type(new Type("mat4x3", *fFloat_Type, 4, 3))
|
||||
, fMat4x4_Type(new Type("mat4", *fFloat_Type, 4, 4))
|
||||
, fDMat2x2_Type(new Type("dmat2", *fFloat_Type, 2, 2))
|
||||
, fDMat2x3_Type(new Type("dmat2x3", *fFloat_Type, 2, 3))
|
||||
, fDMat2x4_Type(new Type("dmat2x4", *fFloat_Type, 2, 4))
|
||||
, fDMat3x2_Type(new Type("dmat3x2", *fFloat_Type, 3, 2))
|
||||
, fDMat3x3_Type(new Type("dmat3", *fFloat_Type, 3, 3))
|
||||
, fDMat3x4_Type(new Type("dmat3x4", *fFloat_Type, 3, 4))
|
||||
, fDMat4x2_Type(new Type("dmat4x2", *fFloat_Type, 4, 2))
|
||||
, fDMat4x3_Type(new Type("dmat4x3", *fFloat_Type, 4, 3))
|
||||
, fDMat4x4_Type(new Type("dmat4", *fFloat_Type, 4, 4))
|
||||
, fSampler1D_Type(new Type("sampler1D", SpvDim1D, false, false, false, true))
|
||||
, fSampler2D_Type(new Type("sampler2D", SpvDim2D, false, false, false, true))
|
||||
, fSampler3D_Type(new Type("sampler3D", SpvDim3D, false, false, false, true))
|
||||
, fSamplerExternalOES_Type(new Type("samplerExternalOES", SpvDim2D, false, false, false, true))
|
||||
, fSamplerCube_Type(new Type("samplerCube"))
|
||||
, fSampler2DRect_Type(new Type("sampler2DRect"))
|
||||
, fSampler1DArray_Type(new Type("sampler1DArray"))
|
||||
, fSampler2DArray_Type(new Type("sampler2DArray"))
|
||||
, fSamplerCubeArray_Type(new Type("samplerCubeArray"))
|
||||
, fSamplerBuffer_Type(new Type("samplerBuffer"))
|
||||
, fSampler2DMS_Type(new Type("sampler2DMS"))
|
||||
, fSampler2DMSArray_Type(new Type("sampler2DMSArray"))
|
||||
, fSampler1DShadow_Type(new Type("sampler1DShadow"))
|
||||
, fSampler2DShadow_Type(new Type("sampler2DShadow"))
|
||||
, fSamplerCubeShadow_Type(new Type("samplerCubeShadow"))
|
||||
, fSampler2DRectShadow_Type(new Type("sampler2DRectShadow"))
|
||||
, fSampler1DArrayShadow_Type(new Type("sampler1DArrayShadow"))
|
||||
, fSampler2DArrayShadow_Type(new Type("sampler2DArrayShadow"))
|
||||
, fSamplerCubeArrayShadow_Type(new Type("samplerCubeArrayShadow"))
|
||||
: fInvalid_Type(new Type(SkString("<INVALID>")))
|
||||
, fVoid_Type(new Type(SkString("void")))
|
||||
, fDouble_Type(new Type(SkString("double"), true))
|
||||
, fDVec2_Type(new Type(SkString("dvec2"), *fDouble_Type, 2))
|
||||
, fDVec3_Type(new Type(SkString("dvec3"), *fDouble_Type, 3))
|
||||
, fDVec4_Type(new Type(SkString("dvec4"), *fDouble_Type, 4))
|
||||
, fFloat_Type(new Type(SkString("float"), true, { fDouble_Type.get() }))
|
||||
, fVec2_Type(new Type(SkString("vec2"), *fFloat_Type, 2))
|
||||
, fVec3_Type(new Type(SkString("vec3"), *fFloat_Type, 3))
|
||||
, fVec4_Type(new Type(SkString("vec4"), *fFloat_Type, 4))
|
||||
, fUInt_Type(new Type(SkString("uint"), true, { fFloat_Type.get(), fDouble_Type.get() }))
|
||||
, fUVec2_Type(new Type(SkString("uvec2"), *fUInt_Type, 2))
|
||||
, fUVec3_Type(new Type(SkString("uvec3"), *fUInt_Type, 3))
|
||||
, fUVec4_Type(new Type(SkString("uvec4"), *fUInt_Type, 4))
|
||||
, fInt_Type(new Type(SkString("int"), true, { fUInt_Type.get(), fFloat_Type.get(),
|
||||
fDouble_Type.get() }))
|
||||
, fIVec2_Type(new Type(SkString("ivec2"), *fInt_Type, 2))
|
||||
, fIVec3_Type(new Type(SkString("ivec3"), *fInt_Type, 3))
|
||||
, fIVec4_Type(new Type(SkString("ivec4"), *fInt_Type, 4))
|
||||
, fBool_Type(new Type(SkString("bool"), false))
|
||||
, fBVec2_Type(new Type(SkString("bvec2"), *fBool_Type, 2))
|
||||
, fBVec3_Type(new Type(SkString("bvec3"), *fBool_Type, 3))
|
||||
, fBVec4_Type(new Type(SkString("bvec4"), *fBool_Type, 4))
|
||||
, fMat2x2_Type(new Type(SkString("mat2"), *fFloat_Type, 2, 2))
|
||||
, fMat2x3_Type(new Type(SkString("mat2x3"), *fFloat_Type, 2, 3))
|
||||
, fMat2x4_Type(new Type(SkString("mat2x4"), *fFloat_Type, 2, 4))
|
||||
, fMat3x2_Type(new Type(SkString("mat3x2"), *fFloat_Type, 3, 2))
|
||||
, fMat3x3_Type(new Type(SkString("mat3"), *fFloat_Type, 3, 3))
|
||||
, fMat3x4_Type(new Type(SkString("mat3x4"), *fFloat_Type, 3, 4))
|
||||
, fMat4x2_Type(new Type(SkString("mat4x2"), *fFloat_Type, 4, 2))
|
||||
, fMat4x3_Type(new Type(SkString("mat4x3"), *fFloat_Type, 4, 3))
|
||||
, fMat4x4_Type(new Type(SkString("mat4"), *fFloat_Type, 4, 4))
|
||||
, fDMat2x2_Type(new Type(SkString("dmat2"), *fFloat_Type, 2, 2))
|
||||
, fDMat2x3_Type(new Type(SkString("dmat2x3"), *fFloat_Type, 2, 3))
|
||||
, fDMat2x4_Type(new Type(SkString("dmat2x4"), *fFloat_Type, 2, 4))
|
||||
, fDMat3x2_Type(new Type(SkString("dmat3x2"), *fFloat_Type, 3, 2))
|
||||
, fDMat3x3_Type(new Type(SkString("dmat3"), *fFloat_Type, 3, 3))
|
||||
, fDMat3x4_Type(new Type(SkString("dmat3x4"), *fFloat_Type, 3, 4))
|
||||
, fDMat4x2_Type(new Type(SkString("dmat4x2"), *fFloat_Type, 4, 2))
|
||||
, fDMat4x3_Type(new Type(SkString("dmat4x3"), *fFloat_Type, 4, 3))
|
||||
, fDMat4x4_Type(new Type(SkString("dmat4"), *fFloat_Type, 4, 4))
|
||||
, fSampler1D_Type(new Type(SkString("sampler1D"), SpvDim1D, false, false, false, true))
|
||||
, fSampler2D_Type(new Type(SkString("sampler2D"), SpvDim2D, false, false, false, true))
|
||||
, fSampler3D_Type(new Type(SkString("sampler3D"), SpvDim3D, false, false, false, true))
|
||||
, fSamplerExternalOES_Type(new Type(SkString("samplerExternalOES"), SpvDim2D, false, false,
|
||||
false, true))
|
||||
, fSamplerCube_Type(new Type(SkString("samplerCube")))
|
||||
, fSampler2DRect_Type(new Type(SkString("sampler2DRect")))
|
||||
, fSampler1DArray_Type(new Type(SkString("sampler1DArray")))
|
||||
, fSampler2DArray_Type(new Type(SkString("sampler2DArray")))
|
||||
, fSamplerCubeArray_Type(new Type(SkString("samplerCubeArray")))
|
||||
, fSamplerBuffer_Type(new Type(SkString("samplerBuffer")))
|
||||
, fSampler2DMS_Type(new Type(SkString("sampler2DMS")))
|
||||
, fSampler2DMSArray_Type(new Type(SkString("sampler2DMSArray")))
|
||||
, fSampler1DShadow_Type(new Type(SkString("sampler1DShadow")))
|
||||
, fSampler2DShadow_Type(new Type(SkString("sampler2DShadow")))
|
||||
, fSamplerCubeShadow_Type(new Type(SkString("samplerCubeShadow")))
|
||||
, fSampler2DRectShadow_Type(new Type(SkString("sampler2DRectShadow")))
|
||||
, fSampler1DArrayShadow_Type(new Type(SkString("sampler1DArrayShadow")))
|
||||
, fSampler2DArrayShadow_Type(new Type(SkString("sampler2DArrayShadow")))
|
||||
, fSamplerCubeArrayShadow_Type(new Type(SkString("samplerCubeArrayShadow")))
|
||||
|
||||
// Related to below FIXME, gsampler*s don't currently expand to cover integer case.
|
||||
, fISampler2D_Type(new Type("isampler2D", SpvDim2D, false, false, false, true))
|
||||
, fISampler2D_Type(new Type(SkString("isampler2D"), SpvDim2D, false, false, false, true))
|
||||
|
||||
// FIXME express these as "gimage2D" that expand to image2D, iimage2D, and uimage2D.
|
||||
, fImage2D_Type(new Type("image2D", SpvDim2D, false, false, false, true))
|
||||
, fIImage2D_Type(new Type("iimage2D", SpvDim2D, false, false, false, true))
|
||||
, fImage2D_Type(new Type(SkString("image2D"), SpvDim2D, false, false, false, true))
|
||||
, fIImage2D_Type(new Type(SkString("iimage2D"), SpvDim2D, false, false, false, true))
|
||||
|
||||
// FIXME figure out what we're supposed to do with the gsampler et al. types)
|
||||
, fGSampler1D_Type(new Type("$gsampler1D", static_type(*fSampler1D_Type)))
|
||||
, fGSampler2D_Type(new Type("$gsampler2D", static_type(*fSampler2D_Type)))
|
||||
, fGSampler3D_Type(new Type("$gsampler3D", static_type(*fSampler3D_Type)))
|
||||
, fGSamplerCube_Type(new Type("$gsamplerCube", static_type(*fSamplerCube_Type)))
|
||||
, fGSampler2DRect_Type(new Type("$gsampler2DRect", static_type(*fSampler2DRect_Type)))
|
||||
, fGSampler1DArray_Type(new Type("$gsampler1DArray", static_type(*fSampler1DArray_Type)))
|
||||
, fGSampler2DArray_Type(new Type("$gsampler2DArray", static_type(*fSampler2DArray_Type)))
|
||||
, fGSamplerCubeArray_Type(new Type("$gsamplerCubeArray", static_type(*fSamplerCubeArray_Type)))
|
||||
, fGSamplerBuffer_Type(new Type("$gsamplerBuffer", static_type(*fSamplerBuffer_Type)))
|
||||
, fGSampler2DMS_Type(new Type("$gsampler2DMS", static_type(*fSampler2DMS_Type)))
|
||||
, fGSampler2DMSArray_Type(new Type("$gsampler2DMSArray", static_type(*fSampler2DMSArray_Type)))
|
||||
, fGSampler2DArrayShadow_Type(new Type("$gsampler2DArrayShadow",
|
||||
, fGSampler1D_Type(new Type(SkString("$gsampler1D"), static_type(*fSampler1D_Type)))
|
||||
, fGSampler2D_Type(new Type(SkString("$gsampler2D"), static_type(*fSampler2D_Type)))
|
||||
, fGSampler3D_Type(new Type(SkString("$gsampler3D"), static_type(*fSampler3D_Type)))
|
||||
, fGSamplerCube_Type(new Type(SkString("$gsamplerCube"), static_type(*fSamplerCube_Type)))
|
||||
, fGSampler2DRect_Type(new Type(SkString("$gsampler2DRect"), static_type(*fSampler2DRect_Type)))
|
||||
, fGSampler1DArray_Type(new Type(SkString("$gsampler1DArray"),
|
||||
static_type(*fSampler1DArray_Type)))
|
||||
, fGSampler2DArray_Type(new Type(SkString("$gsampler2DArray"),
|
||||
static_type(*fSampler2DArray_Type)))
|
||||
, fGSamplerCubeArray_Type(new Type(SkString("$gsamplerCubeArray"),
|
||||
static_type(*fSamplerCubeArray_Type)))
|
||||
, fGSamplerBuffer_Type(new Type(SkString("$gsamplerBuffer"), static_type(*fSamplerBuffer_Type)))
|
||||
, fGSampler2DMS_Type(new Type(SkString("$gsampler2DMS"), static_type(*fSampler2DMS_Type)))
|
||||
, fGSampler2DMSArray_Type(new Type(SkString("$gsampler2DMSArray"),
|
||||
static_type(*fSampler2DMSArray_Type)))
|
||||
, fGSampler2DArrayShadow_Type(new Type(SkString("$gsampler2DArrayShadow"),
|
||||
static_type(*fSampler2DArrayShadow_Type)))
|
||||
, fGSamplerCubeArrayShadow_Type(new Type("$gsamplerCubeArrayShadow",
|
||||
, fGSamplerCubeArrayShadow_Type(new Type(SkString("$gsamplerCubeArrayShadow"),
|
||||
static_type(*fSamplerCubeArrayShadow_Type)))
|
||||
, fGenType_Type(new Type("$genType", { fFloat_Type.get(), fVec2_Type.get(), fVec3_Type.get(),
|
||||
fVec4_Type.get() }))
|
||||
, fGenDType_Type(new Type("$genDType", { fDouble_Type.get(), fDVec2_Type.get(),
|
||||
fDVec3_Type.get(), fDVec4_Type.get() }))
|
||||
, fGenIType_Type(new Type("$genIType", { fInt_Type.get(), fIVec2_Type.get(), fIVec3_Type.get(),
|
||||
fIVec4_Type.get() }))
|
||||
, fGenUType_Type(new Type("$genUType", { fUInt_Type.get(), fUVec2_Type.get(), fUVec3_Type.get(),
|
||||
fUVec4_Type.get() }))
|
||||
, fGenBType_Type(new Type("$genBType", { fBool_Type.get(), fBVec2_Type.get(), fBVec3_Type.get(),
|
||||
fBVec4_Type.get() }))
|
||||
, fMat_Type(new Type("$mat"))
|
||||
, fVec_Type(new Type("$vec", { fInvalid_Type.get(), fVec2_Type.get(), fVec3_Type.get(),
|
||||
fVec4_Type.get() }))
|
||||
, fGVec_Type(new Type("$gvec"))
|
||||
, fGVec2_Type(new Type("$gvec2"))
|
||||
, fGVec3_Type(new Type("$gvec3"))
|
||||
, fGVec4_Type(new Type("$gvec4", static_type(*fVec4_Type)))
|
||||
, fDVec_Type(new Type("$dvec", { fInvalid_Type.get(), fDVec2_Type.get(), fDVec3_Type.get(),
|
||||
fDVec4_Type.get() }))
|
||||
, fIVec_Type(new Type("$ivec", { fInvalid_Type.get(), fIVec2_Type.get(), fIVec3_Type.get(),
|
||||
fIVec4_Type.get() }))
|
||||
, fUVec_Type(new Type("$uvec", { fInvalid_Type.get(), fUVec2_Type.get(), fUVec3_Type.get(),
|
||||
fUVec4_Type.get() }))
|
||||
, fBVec_Type(new Type("$bvec", { fInvalid_Type.get(), fBVec2_Type.get(), fBVec3_Type.get(),
|
||||
fBVec4_Type.get() }))
|
||||
, fGenType_Type(new Type(SkString("$genType"), { fFloat_Type.get(), fVec2_Type.get(),
|
||||
fVec3_Type.get(), fVec4_Type.get() }))
|
||||
, fGenDType_Type(new Type(SkString("$genDType"), { fDouble_Type.get(), fDVec2_Type.get(),
|
||||
fDVec3_Type.get(), fDVec4_Type.get() }))
|
||||
, fGenIType_Type(new Type(SkString("$genIType"), { fInt_Type.get(), fIVec2_Type.get(),
|
||||
fIVec3_Type.get(), fIVec4_Type.get() }))
|
||||
, fGenUType_Type(new Type(SkString("$genUType"), { fUInt_Type.get(), fUVec2_Type.get(),
|
||||
fUVec3_Type.get(), fUVec4_Type.get() }))
|
||||
, fGenBType_Type(new Type(SkString("$genBType"), { fBool_Type.get(), fBVec2_Type.get(),
|
||||
fBVec3_Type.get(), fBVec4_Type.get() }))
|
||||
, fMat_Type(new Type(SkString("$mat")))
|
||||
, fVec_Type(new Type(SkString("$vec"), { fInvalid_Type.get(), fVec2_Type.get(),
|
||||
fVec3_Type.get(), fVec4_Type.get() }))
|
||||
, fGVec_Type(new Type(SkString("$gvec")))
|
||||
, fGVec2_Type(new Type(SkString("$gvec2")))
|
||||
, fGVec3_Type(new Type(SkString("$gvec3")))
|
||||
, fGVec4_Type(new Type(SkString("$gvec4"), static_type(*fVec4_Type)))
|
||||
, fDVec_Type(new Type(SkString("$dvec"), { fInvalid_Type.get(), fDVec2_Type.get(),
|
||||
fDVec3_Type.get(), fDVec4_Type.get() }))
|
||||
, fIVec_Type(new Type(SkString("$ivec"), { fInvalid_Type.get(), fIVec2_Type.get(),
|
||||
fIVec3_Type.get(), fIVec4_Type.get() }))
|
||||
, fUVec_Type(new Type(SkString("$uvec"), { fInvalid_Type.get(), fUVec2_Type.get(),
|
||||
fUVec3_Type.get(), fUVec4_Type.get() }))
|
||||
, fBVec_Type(new Type(SkString("$bvec"), { fInvalid_Type.get(), fBVec2_Type.get(),
|
||||
fBVec3_Type.get(), fBVec4_Type.get() }))
|
||||
, fDefined_Expression(new Defined(*fInvalid_Type)) {}
|
||||
|
||||
static std::vector<const Type*> static_type(const Type& t) {
|
||||
@ -252,8 +258,8 @@ private:
|
||||
Defined(const Type& type)
|
||||
: INHERITED(Position(), kDefined_Kind, type) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
return "<defined>";
|
||||
virtual SkString description() const override {
|
||||
return SkString("<defined>");
|
||||
}
|
||||
|
||||
typedef Expression INHERITED;
|
||||
|
@ -19,7 +19,11 @@ class ErrorReporter {
|
||||
public:
|
||||
virtual ~ErrorReporter() {}
|
||||
|
||||
virtual void error(Position position, std::string msg) = 0;
|
||||
void error(Position position, const char* msg) {
|
||||
this->error(position, SkString(msg));
|
||||
}
|
||||
|
||||
virtual void error(Position position, SkString msg) = 0;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -27,24 +27,24 @@ void GLSLCodeGenerator::write(const char* s) {
|
||||
}
|
||||
if (fAtLineStart) {
|
||||
for (int i = 0; i < fIndentation; i++) {
|
||||
*fOut << " ";
|
||||
fOut->writeText(" ");
|
||||
}
|
||||
}
|
||||
*fOut << s;
|
||||
fOut->writeText(s);
|
||||
fAtLineStart = false;
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeLine(const char* s) {
|
||||
this->write(s);
|
||||
*fOut << "\n";
|
||||
fOut->writeText("\n");
|
||||
fAtLineStart = true;
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::write(const std::string& s) {
|
||||
void GLSLCodeGenerator::write(const SkString& s) {
|
||||
this->write(s.c_str());
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeLine(const std::string& s) {
|
||||
void GLSLCodeGenerator::writeLine(const SkString& s) {
|
||||
this->writeLine(s.c_str());
|
||||
}
|
||||
|
||||
@ -138,8 +138,8 @@ static bool is_abs(Expression& expr) {
|
||||
// Tegra3 compiler bug.
|
||||
void GLSLCodeGenerator::writeMinAbsHack(Expression& absExpr, Expression& otherExpr) {
|
||||
ASSERT(!fCaps.canUseMinAndAbsTogether());
|
||||
std::string tmpVar1 = "minAbsHackVar" + to_string(fVarCount++);
|
||||
std::string tmpVar2 = "minAbsHackVar" + to_string(fVarCount++);
|
||||
SkString tmpVar1 = "minAbsHackVar" + to_string(fVarCount++);
|
||||
SkString tmpVar2 = "minAbsHackVar" + to_string(fVarCount++);
|
||||
this->fFunctionHeader += " " + absExpr.fType.name() + " " + tmpVar1 + ";\n";
|
||||
this->fFunctionHeader += " " + otherExpr.fType.name() + " " + tmpVar2 + ";\n";
|
||||
this->write("((" + tmpVar1 + " = ");
|
||||
@ -179,7 +179,9 @@ void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) {
|
||||
if (!fFoundDerivatives && (c.fFunction.fName == "dFdx" || c.fFunction.fName == "dFdy") &&
|
||||
c.fFunction.fBuiltin && fCaps.shaderDerivativeExtensionString()) {
|
||||
ASSERT(fCaps.shaderDerivativeSupport());
|
||||
fHeader << "#extension " << fCaps.shaderDerivativeExtensionString() << " : require\n";
|
||||
fHeader.writeText("#extension ");
|
||||
fHeader.writeText(fCaps.shaderDerivativeExtensionString());
|
||||
fHeader.writeText(" : require\n");
|
||||
fFoundDerivatives = true;
|
||||
}
|
||||
this->write(c.fFunction.fName + "(");
|
||||
@ -373,8 +375,8 @@ void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
|
||||
this->writeLine(") {");
|
||||
|
||||
fFunctionHeader = "";
|
||||
std::ostream* oldOut = fOut;
|
||||
std::stringstream buffer;
|
||||
SkWStream* oldOut = fOut;
|
||||
SkDynamicMemoryWStream buffer;
|
||||
fOut = &buffer;
|
||||
fIndentation++;
|
||||
for (const auto& s : f.fBody->fStatements) {
|
||||
@ -386,7 +388,8 @@ void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
|
||||
|
||||
fOut = oldOut;
|
||||
this->write(fFunctionHeader);
|
||||
this->write(buffer.str());
|
||||
sk_sp<SkData> data(buffer.detachAsData());
|
||||
this->write(SkString((const char*) data->data(), data->size()));
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers,
|
||||
@ -397,8 +400,8 @@ void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers,
|
||||
if (modifiers.fFlags & Modifiers::kFlat_Flag) {
|
||||
this->write("flat ");
|
||||
}
|
||||
std::string layout = modifiers.fLayout.description();
|
||||
if (layout.length()) {
|
||||
SkString layout = modifiers.fLayout.description();
|
||||
if (layout.size()) {
|
||||
this->write(layout + " ");
|
||||
}
|
||||
if ((modifiers.fFlags & Modifiers::kIn_Flag) &&
|
||||
@ -457,11 +460,11 @@ void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool g
|
||||
ASSERT(decl.fVars.size() > 0);
|
||||
this->writeModifiers(decl.fVars[0].fVar->fModifiers, global);
|
||||
this->writeType(decl.fBaseType);
|
||||
std::string separator = " ";
|
||||
SkString separator(" ");
|
||||
for (const auto& var : decl.fVars) {
|
||||
ASSERT(var.fVar->fModifiers == decl.fVars[0].fVar->fModifiers);
|
||||
this->write(separator);
|
||||
separator = ", ";
|
||||
separator = SkString(", ");
|
||||
this->write(var.fVar->fName);
|
||||
for (const auto& size : var.fSizes) {
|
||||
this->write("[");
|
||||
@ -476,7 +479,9 @@ void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool g
|
||||
}
|
||||
if (!fFoundImageDecl && var.fVar->fType == *fContext.fImage2D_Type) {
|
||||
if (fCaps.imageLoadStoreExtensionString()) {
|
||||
fHeader << "#extension " << fCaps.imageLoadStoreExtensionString() << " : require\n";
|
||||
fHeader.writeText("#extension ");
|
||||
fHeader.writeText(fCaps.imageLoadStoreExtensionString());
|
||||
fHeader.writeText(" : require\n");
|
||||
}
|
||||
fFoundImageDecl = true;
|
||||
}
|
||||
@ -589,7 +594,7 @@ void GLSLCodeGenerator::writeReturnStatement(const ReturnStatement& r) {
|
||||
this->write(";");
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) {
|
||||
void GLSLCodeGenerator::generateCode(const Program& program, SkWStream& out) {
|
||||
ASSERT(fOut == nullptr);
|
||||
fOut = &fHeader;
|
||||
fProgramKind = program.fKind;
|
||||
@ -600,7 +605,7 @@ void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out)
|
||||
this->writeExtension((Extension&) *e);
|
||||
}
|
||||
}
|
||||
std::stringstream body;
|
||||
SkDynamicMemoryWStream body;
|
||||
fOut = &body;
|
||||
if (fCaps.usesPrecisionModifiers()) {
|
||||
this->write("precision ");
|
||||
@ -660,8 +665,8 @@ void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out)
|
||||
}
|
||||
fOut = nullptr;
|
||||
|
||||
out << fHeader.str();
|
||||
out << body.str();
|
||||
write_data(*fHeader.detachAsData(), out);
|
||||
write_data(*body.detachAsData(), out);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "SkStream.h"
|
||||
#include "glsl/GrGLSLCaps.h"
|
||||
#include "SkSLCodeGenerator.h"
|
||||
#include "ir/SkSLBinaryExpression.h"
|
||||
@ -75,7 +76,7 @@ public:
|
||||
: fContext(*context)
|
||||
, fCaps(*caps) {}
|
||||
|
||||
void generateCode(const Program& program, std::ostream& out) override;
|
||||
void generateCode(const Program& program, SkWStream& out) override;
|
||||
|
||||
private:
|
||||
void write(const char* s);
|
||||
@ -84,9 +85,9 @@ private:
|
||||
|
||||
void writeLine(const char* s);
|
||||
|
||||
void write(const std::string& s);
|
||||
void write(const SkString& s);
|
||||
|
||||
void writeLine(const std::string& s);
|
||||
void writeLine(const SkString& s);
|
||||
|
||||
void writeType(const Type& type);
|
||||
|
||||
@ -156,9 +157,9 @@ private:
|
||||
|
||||
const Context& fContext;
|
||||
const GrGLSLCaps& fCaps;
|
||||
std::ostream* fOut = nullptr;
|
||||
std::stringstream fHeader;
|
||||
std::string fFunctionHeader;
|
||||
SkWStream* fOut = nullptr;
|
||||
SkDynamicMemoryWStream fHeader;
|
||||
SkString fFunctionHeader;
|
||||
Program::Kind fProgramKind;
|
||||
int fVarCount = 0;
|
||||
int fIndentation = 0;
|
||||
|
@ -173,7 +173,7 @@ std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTVa
|
||||
if (!size) {
|
||||
return nullptr;
|
||||
}
|
||||
std::string name = type->fName;
|
||||
SkString name = type->fName;
|
||||
uint64_t count;
|
||||
if (size->fKind == Expression::kIntLiteral_Kind) {
|
||||
count = ((IntLiteral&) *size).fValue;
|
||||
@ -204,7 +204,7 @@ std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTVa
|
||||
}
|
||||
value = this->coerce(std::move(value), *type);
|
||||
}
|
||||
if (storage == Variable::kGlobal_Storage && "sk_FragColor" == varDecl.fName &&
|
||||
if (storage == Variable::kGlobal_Storage && varDecl.fName == SkString("sk_FragColor") &&
|
||||
(*fSymbolTable)[varDecl.fName]) {
|
||||
// already defined, ignore
|
||||
} else if (storage == Variable::kGlobal_Storage && (*fSymbolTable)[varDecl.fName] &&
|
||||
@ -397,12 +397,12 @@ std::unique_ptr<FunctionDefinition> IRGenerator::convertFunction(const ASTFuncti
|
||||
}
|
||||
for (int j = (int) param->fSizes.size() - 1; j >= 0; j--) {
|
||||
int size = param->fSizes[j];
|
||||
std::string name = type->name() + "[" + to_string(size) + "]";
|
||||
SkString name = type->name() + "[" + to_string(size) + "]";
|
||||
Type* newType = new Type(std::move(name), Type::kArray_Kind, *type, size);
|
||||
fSymbolTable->takeOwnership(newType);
|
||||
type = newType;
|
||||
}
|
||||
std::string name = param->fName;
|
||||
SkString name = param->fName;
|
||||
Modifiers modifiers = this->convertModifiers(param->fModifiers);
|
||||
Position pos = param->fPosition;
|
||||
Variable* var = new Variable(pos, modifiers, std::move(name), *type,
|
||||
@ -523,10 +523,10 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte
|
||||
}
|
||||
Type* type = new Type(intf.fInterfaceName, fields);
|
||||
fSymbolTable->takeOwnership(type);
|
||||
std::string name = intf.fValueName.length() > 0 ? intf.fValueName : intf.fInterfaceName;
|
||||
SkString name = intf.fValueName.size() > 0 ? intf.fValueName : intf.fInterfaceName;
|
||||
Variable* var = new Variable(intf.fPosition, mods, name, *type, Variable::kGlobal_Storage);
|
||||
fSymbolTable->takeOwnership(var);
|
||||
if (intf.fValueName.length()) {
|
||||
if (intf.fValueName.size()) {
|
||||
old->addWithoutOwnership(intf.fValueName, var);
|
||||
} else {
|
||||
for (size_t i = 0; i < fields.size(); i++) {
|
||||
@ -966,7 +966,7 @@ std::unique_ptr<Expression> IRGenerator::call(Position position,
|
||||
const FunctionDeclaration& function,
|
||||
std::vector<std::unique_ptr<Expression>> arguments) {
|
||||
if (function.fParameters.size() != arguments.size()) {
|
||||
std::string msg = "call to '" + function.fName + "' expected " +
|
||||
SkString msg = "call to '" + function.fName + "' expected " +
|
||||
to_string((uint64_t) function.fParameters.size()) +
|
||||
" argument";
|
||||
if (function.fParameters.size() != 1) {
|
||||
@ -979,8 +979,8 @@ std::unique_ptr<Expression> IRGenerator::call(Position position,
|
||||
std::vector<const Type*> types;
|
||||
const Type* returnType;
|
||||
if (!function.determineFinalTypes(arguments, &types, &returnType)) {
|
||||
std::string msg = "no match for " + function.fName + "(";
|
||||
std::string separator = "";
|
||||
SkString msg = "no match for " + function.fName + "(";
|
||||
SkString separator;
|
||||
for (size_t i = 0; i < arguments.size(); i++) {
|
||||
msg += separator;
|
||||
separator = ", ";
|
||||
@ -1058,8 +1058,8 @@ std::unique_ptr<Expression> IRGenerator::call(Position position,
|
||||
if (best) {
|
||||
return this->call(position, *best, std::move(arguments));
|
||||
}
|
||||
std::string msg = "no match for " + ref->fFunctions[0]->fName + "(";
|
||||
std::string separator = "";
|
||||
SkString msg = "no match for " + ref->fFunctions[0]->fName + "(";
|
||||
SkString separator;
|
||||
for (size_t i = 0; i < arguments.size(); i++) {
|
||||
msg += separator;
|
||||
separator = ", ";
|
||||
@ -1267,7 +1267,7 @@ std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression> base,
|
||||
const std::string& field) {
|
||||
const SkString& field) {
|
||||
auto fields = base->fType.fields();
|
||||
for (size_t i = 0; i < fields.size(); i++) {
|
||||
if (fields[i].fName == field) {
|
||||
@ -1280,14 +1280,14 @@ std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expression> base,
|
||||
const std::string& fields) {
|
||||
const SkString& fields) {
|
||||
if (base->fType.kind() != Type::kVector_Kind) {
|
||||
fErrors.error(base->fPosition, "cannot swizzle type '" + base->fType.description() + "'");
|
||||
return nullptr;
|
||||
}
|
||||
std::vector<int> swizzleComponents;
|
||||
for (char c : fields) {
|
||||
switch (c) {
|
||||
for (size_t i = 0; i < fields.size(); i++) {
|
||||
switch (fields[i]) {
|
||||
case 'x': // fall through
|
||||
case 'r': // fall through
|
||||
case 's':
|
||||
@ -1318,8 +1318,8 @@ std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expressi
|
||||
}
|
||||
// fall through
|
||||
default:
|
||||
fErrors.error(base->fPosition, "invalid swizzle component '" + std::string(1, c) +
|
||||
"'");
|
||||
fErrors.error(base->fPosition, SkStringPrintf("invalid swizzle component '%c'",
|
||||
fields[i]));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -107,9 +107,9 @@ private:
|
||||
std::unique_ptr<Statement> convertReturn(const ASTReturnStatement& r);
|
||||
std::unique_ptr<Expression> convertSuffixExpression(const ASTSuffixExpression& expression);
|
||||
std::unique_ptr<Expression> convertField(std::unique_ptr<Expression> base,
|
||||
const std::string& field);
|
||||
const SkString& field);
|
||||
std::unique_ptr<Expression> convertSwizzle(std::unique_ptr<Expression> base,
|
||||
const std::string& fields);
|
||||
const SkString& fields);
|
||||
std::unique_ptr<Expression> convertTernaryExpression(const ASTTernaryExpression& expression);
|
||||
std::unique_ptr<Statement> convertVarDeclarationStatement(const ASTVarDeclarationStatement& s);
|
||||
std::unique_ptr<Statement> convertWhile(const ASTWhileStatement& w);
|
||||
|
@ -10,13 +10,6 @@
|
||||
#include "SkSLCompiler.h"
|
||||
#include "GrContextOptions.h"
|
||||
|
||||
bool endsWith(const std::string& s, const std::string& ending) {
|
||||
if (s.length() >= ending.length()) {
|
||||
return (0 == s.compare(s.length() - ending.length(), ending.length(), ending));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Very simple standalone executable to facilitate testing.
|
||||
*/
|
||||
@ -37,35 +30,36 @@ int main(int argc, const char** argv) {
|
||||
}
|
||||
|
||||
std::ifstream in(argv[1]);
|
||||
std::string text((std::istreambuf_iterator<char>(in)),
|
||||
std::istreambuf_iterator<char>());
|
||||
std::string stdText((std::istreambuf_iterator<char>(in)),
|
||||
std::istreambuf_iterator<char>());
|
||||
SkString text(stdText.c_str());
|
||||
if (in.rdstate()) {
|
||||
printf("error reading '%s'\n", argv[1]);
|
||||
exit(2);
|
||||
}
|
||||
std::string name(argv[2]);
|
||||
if (endsWith(name, ".spirv")) {
|
||||
std::ofstream out(argv[2], std::ofstream::binary);
|
||||
SkString name(argv[2]);
|
||||
if (name.endsWith(".spirv")) {
|
||||
SkFILEWStream out(argv[2]);
|
||||
SkSL::Compiler compiler;
|
||||
if (!out.isValid()) {
|
||||
printf("error writing '%s'\n", argv[2]);
|
||||
exit(4);
|
||||
}
|
||||
if (!compiler.toSPIRV(kind, text, out)) {
|
||||
printf("%s", compiler.errorText().c_str());
|
||||
exit(3);
|
||||
}
|
||||
if (out.rdstate()) {
|
||||
} else if (name.endsWith(".glsl")) {
|
||||
SkFILEWStream out(argv[2]);
|
||||
SkSL::Compiler compiler;
|
||||
if (!out.isValid()) {
|
||||
printf("error writing '%s'\n", argv[2]);
|
||||
exit(4);
|
||||
}
|
||||
} else if (endsWith(name, ".glsl")) {
|
||||
std::ofstream out(argv[2], std::ofstream::binary);
|
||||
SkSL::Compiler compiler;
|
||||
if (!compiler.toGLSL(kind, text, *SkSL::GLSLCapsFactory::Default(), out)) {
|
||||
printf("%s", compiler.errorText().c_str());
|
||||
exit(3);
|
||||
}
|
||||
if (out.rdstate()) {
|
||||
printf("error writing '%s'\n", argv[2]);
|
||||
exit(4);
|
||||
}
|
||||
} else {
|
||||
printf("expected output filename to end with '.spirv' or '.glsl'");
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ public:
|
||||
|
||||
bool checkValid() {
|
||||
if (fParser->fDepth > MAX_PARSE_DEPTH) {
|
||||
fParser->error(fParser->peek().fPosition, "exceeded max parse depth");
|
||||
fParser->error(fParser->peek().fPosition, SkString("exceeded max parse depth"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -98,8 +98,8 @@ private:
|
||||
Parser* fParser;
|
||||
};
|
||||
|
||||
Parser::Parser(std::string text, SymbolTable& types, ErrorReporter& errors)
|
||||
: fPushback(Position(-1, -1), Token::INVALID_TOKEN, "")
|
||||
Parser::Parser(SkString text, SymbolTable& types, ErrorReporter& errors)
|
||||
: fPushback(Position(-1, -1), Token::INVALID_TOKEN, SkString())
|
||||
, fTypes(types)
|
||||
, fErrors(errors) {
|
||||
sksllex_init(&fScanner);
|
||||
@ -157,13 +157,13 @@ Token Parser::nextToken() {
|
||||
return result;
|
||||
}
|
||||
int token = sksllex(fScanner);
|
||||
std::string text;
|
||||
SkString text;
|
||||
switch ((Token::Kind) token) {
|
||||
case Token::IDENTIFIER: // fall through
|
||||
case Token::INT_LITERAL: // fall through
|
||||
case Token::FLOAT_LITERAL: // fall through
|
||||
case Token::DIRECTIVE:
|
||||
text = std::string(skslget_text(fScanner));
|
||||
text = SkString(skslget_text(fScanner));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -181,7 +181,12 @@ Token Parser::peek() {
|
||||
return fPushback;
|
||||
}
|
||||
|
||||
bool Parser::expect(Token::Kind kind, std::string expected, Token* result) {
|
||||
|
||||
bool Parser::expect(Token::Kind kind, const char* expected, Token* result) {
|
||||
return this->expect(kind, SkString(expected), result);
|
||||
}
|
||||
|
||||
bool Parser::expect(Token::Kind kind, SkString expected, Token* result) {
|
||||
Token next = this->nextToken();
|
||||
if (next.fKind == kind) {
|
||||
if (result) {
|
||||
@ -194,11 +199,15 @@ bool Parser::expect(Token::Kind kind, std::string expected, Token* result) {
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::error(Position p, std::string msg) {
|
||||
void Parser::error(Position p, const char* msg) {
|
||||
this->error(p, SkString(msg));
|
||||
}
|
||||
|
||||
void Parser::error(Position p, SkString msg) {
|
||||
fErrors.error(p, msg);
|
||||
}
|
||||
|
||||
bool Parser::isType(std::string name) {
|
||||
bool Parser::isType(SkString name) {
|
||||
return nullptr != fTypes[name];
|
||||
}
|
||||
|
||||
@ -370,7 +379,7 @@ std::unique_ptr<ASTType> Parser::structDeclaration() {
|
||||
return nullptr;
|
||||
}
|
||||
uint64_t columns = ((ASTIntLiteral&) *var.fSizes[i]).fValue;
|
||||
std::string name = type->name() + "[" + to_string(columns) + "]";
|
||||
SkString name = type->name() + "[" + to_string(columns) + "]";
|
||||
type = new Type(name, Type::kArray_Kind, *type, (int) columns);
|
||||
fTypes.takeOwnership((Type*) type);
|
||||
}
|
||||
@ -417,7 +426,7 @@ std::unique_ptr<ASTVarDeclarations> Parser::structVarDeclaration(ASTModifiers mo
|
||||
(LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */
|
||||
std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(ASTModifiers mods,
|
||||
std::unique_ptr<ASTType> type,
|
||||
std::string name) {
|
||||
SkString name) {
|
||||
std::vector<ASTVarDeclaration> vars;
|
||||
std::vector<std::unique_ptr<ASTExpression>> currentVarSizes;
|
||||
while (this->peek().fKind == Token::LBRACKET) {
|
||||
@ -731,7 +740,7 @@ std::unique_ptr<ASTDeclaration> Parser::interfaceBlock(ASTModifiers mods) {
|
||||
decls.push_back(std::move(decl));
|
||||
}
|
||||
this->nextToken();
|
||||
std::string valueName;
|
||||
SkString valueName;
|
||||
if (this->peek().fKind == Token::IDENTIFIER) {
|
||||
valueName = this->nextToken().fText;
|
||||
}
|
||||
@ -1361,7 +1370,7 @@ std::unique_ptr<ASTSuffix> Parser::suffix() {
|
||||
}
|
||||
case Token::DOT: {
|
||||
Position pos = this->peek().fPosition;
|
||||
std::string text;
|
||||
SkString text;
|
||||
if (this->identifier(&text)) {
|
||||
return std::unique_ptr<ASTSuffix>(new ASTFieldSuffix(pos, std::move(text)));
|
||||
}
|
||||
@ -1406,7 +1415,7 @@ std::unique_ptr<ASTExpression> Parser::term() {
|
||||
Token t = this->peek();
|
||||
switch (t.fKind) {
|
||||
case Token::IDENTIFIER: {
|
||||
std::string text;
|
||||
SkString text;
|
||||
if (this->identifier(&text)) {
|
||||
result.reset(new ASTIdentifier(t.fPosition, std::move(text)));
|
||||
}
|
||||
@ -1487,7 +1496,7 @@ bool Parser::boolLiteral(bool* dest) {
|
||||
}
|
||||
|
||||
/* IDENTIFIER */
|
||||
bool Parser::identifier(std::string* dest) {
|
||||
bool Parser::identifier(SkString* dest) {
|
||||
Token t;
|
||||
if (this->expect(Token::IDENTIFIER, "identifier", &t)) {
|
||||
*dest = t.fText;
|
||||
|
@ -8,7 +8,6 @@
|
||||
#ifndef SKSL_PARSER
|
||||
#define SKSL_PARSER
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
@ -49,7 +48,7 @@ class SymbolTable;
|
||||
*/
|
||||
class Parser {
|
||||
public:
|
||||
Parser(std::string text, SymbolTable& types, ErrorReporter& errors);
|
||||
Parser(SkString text, SymbolTable& types, ErrorReporter& errors);
|
||||
|
||||
~Parser();
|
||||
|
||||
@ -87,15 +86,17 @@ private:
|
||||
* If 'result' is non-null, it is set to point to the token that was read.
|
||||
* Returns true if the read token was as expected, false otherwise.
|
||||
*/
|
||||
bool expect(Token::Kind kind, std::string expected, Token* result = nullptr);
|
||||
bool expect(Token::Kind kind, const char* expected, Token* result = nullptr);
|
||||
bool expect(Token::Kind kind, SkString expected, Token* result = nullptr);
|
||||
|
||||
void error(Position p, std::string msg);
|
||||
void error(Position p, const char* msg);
|
||||
void error(Position p, SkString msg);
|
||||
|
||||
/**
|
||||
* Returns true if the 'name' identifier refers to a type name. For instance, isType("int") will
|
||||
* always return true.
|
||||
*/
|
||||
bool isType(std::string name);
|
||||
bool isType(SkString name);
|
||||
|
||||
// these functions parse individual grammar rules from the current parse position; you probably
|
||||
// don't need to call any of these outside of the parser. The function declarations in the .cpp
|
||||
@ -115,7 +116,7 @@ private:
|
||||
|
||||
std::unique_ptr<ASTVarDeclarations> varDeclarationEnd(ASTModifiers modifiers,
|
||||
std::unique_ptr<ASTType> type,
|
||||
std::string name);
|
||||
SkString name);
|
||||
|
||||
std::unique_ptr<ASTParameter> parameter();
|
||||
|
||||
@ -195,7 +196,7 @@ private:
|
||||
|
||||
bool boolLiteral(bool* dest);
|
||||
|
||||
bool identifier(std::string* dest);
|
||||
bool identifier(SkString* dest);
|
||||
|
||||
void* fScanner;
|
||||
YY_BUFFER_STATE fBuffer;
|
||||
|
@ -25,7 +25,7 @@ struct Position {
|
||||
: fLine(line)
|
||||
, fColumn(column) {}
|
||||
|
||||
std::string description() const {
|
||||
SkString description() const {
|
||||
return to_string(fLine);
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,11 +8,11 @@
|
||||
#ifndef SKSL_SPIRVCODEGENERATOR
|
||||
#define SKSL_SPIRVCODEGENERATOR
|
||||
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "SkStream.h"
|
||||
#include "SkSLCodeGenerator.h"
|
||||
#include "ir/SkSLBinaryExpression.h"
|
||||
#include "ir/SkSLBoolLiteral.h"
|
||||
@ -56,9 +56,9 @@ public:
|
||||
// by a pointer (e.g. vector swizzles), returns 0.
|
||||
virtual SpvId getPointer() = 0;
|
||||
|
||||
virtual SpvId load(std::ostream& out) = 0;
|
||||
virtual SpvId load(SkWStream& out) = 0;
|
||||
|
||||
virtual void store(SpvId value, std::ostream& out) = 0;
|
||||
virtual void store(SpvId value, SkWStream& out) = 0;
|
||||
};
|
||||
|
||||
SPIRVCodeGenerator(const Context* context)
|
||||
@ -71,7 +71,7 @@ public:
|
||||
this->setupIntrinsics();
|
||||
}
|
||||
|
||||
void generateCode(const Program& program, std::ostream& out) override;
|
||||
void generateCode(const Program& program, SkWStream& out) override;
|
||||
|
||||
private:
|
||||
enum IntrinsicKind {
|
||||
@ -97,7 +97,7 @@ private:
|
||||
|
||||
SpvId getPointerType(const Type& type, SpvStorageClass_ storageClass);
|
||||
|
||||
std::vector<SpvId> getAccessChain(const Expression& expr, std::ostream& out);
|
||||
std::vector<SpvId> getAccessChain(const Expression& expr, SkWStream& out);
|
||||
|
||||
void writeLayout(const Layout& layout, SpvId target);
|
||||
|
||||
@ -105,68 +105,68 @@ private:
|
||||
|
||||
void writeStruct(const Type& type, SpvId resultId);
|
||||
|
||||
void writeProgramElement(const ProgramElement& pe, std::ostream& out);
|
||||
void writeProgramElement(const ProgramElement& pe, SkWStream& out);
|
||||
|
||||
SpvId writeInterfaceBlock(const InterfaceBlock& intf);
|
||||
|
||||
SpvId writeFunctionStart(const FunctionDeclaration& f, std::ostream& out);
|
||||
SpvId writeFunctionStart(const FunctionDeclaration& f, SkWStream& out);
|
||||
|
||||
SpvId writeFunctionDeclaration(const FunctionDeclaration& f, std::ostream& out);
|
||||
SpvId writeFunctionDeclaration(const FunctionDeclaration& f, SkWStream& out);
|
||||
|
||||
SpvId writeFunction(const FunctionDefinition& f, std::ostream& out);
|
||||
SpvId writeFunction(const FunctionDefinition& f, SkWStream& out);
|
||||
|
||||
void writeGlobalVars(Program::Kind kind, const VarDeclarations& v, std::ostream& out);
|
||||
void writeGlobalVars(Program::Kind kind, const VarDeclarations& v, SkWStream& out);
|
||||
|
||||
void writeVarDeclarations(const VarDeclarations& decl, std::ostream& out);
|
||||
void writeVarDeclarations(const VarDeclarations& decl, SkWStream& out);
|
||||
|
||||
SpvId writeVariableReference(const VariableReference& ref, std::ostream& out);
|
||||
SpvId writeVariableReference(const VariableReference& ref, SkWStream& out);
|
||||
|
||||
std::unique_ptr<LValue> getLValue(const Expression& value, std::ostream& out);
|
||||
std::unique_ptr<LValue> getLValue(const Expression& value, SkWStream& out);
|
||||
|
||||
SpvId writeExpression(const Expression& expr, std::ostream& out);
|
||||
SpvId writeExpression(const Expression& expr, SkWStream& out);
|
||||
|
||||
SpvId writeIntrinsicCall(const FunctionCall& c, std::ostream& out);
|
||||
SpvId writeIntrinsicCall(const FunctionCall& c, SkWStream& out);
|
||||
|
||||
SpvId writeFunctionCall(const FunctionCall& c, std::ostream& out);
|
||||
SpvId writeFunctionCall(const FunctionCall& c, SkWStream& out);
|
||||
|
||||
SpvId writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind, std::ostream& out);
|
||||
SpvId writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind, SkWStream& out);
|
||||
|
||||
SpvId writeConstantVector(const Constructor& c);
|
||||
|
||||
SpvId writeFloatConstructor(const Constructor& c, std::ostream& out);
|
||||
SpvId writeFloatConstructor(const Constructor& c, SkWStream& out);
|
||||
|
||||
SpvId writeIntConstructor(const Constructor& c, std::ostream& out);
|
||||
SpvId writeIntConstructor(const Constructor& c, SkWStream& out);
|
||||
|
||||
SpvId writeMatrixConstructor(const Constructor& c, std::ostream& out);
|
||||
SpvId writeMatrixConstructor(const Constructor& c, SkWStream& out);
|
||||
|
||||
SpvId writeVectorConstructor(const Constructor& c, std::ostream& out);
|
||||
SpvId writeVectorConstructor(const Constructor& c, SkWStream& out);
|
||||
|
||||
SpvId writeConstructor(const Constructor& c, std::ostream& out);
|
||||
SpvId writeConstructor(const Constructor& c, SkWStream& out);
|
||||
|
||||
SpvId writeFieldAccess(const FieldAccess& f, std::ostream& out);
|
||||
SpvId writeFieldAccess(const FieldAccess& f, SkWStream& out);
|
||||
|
||||
SpvId writeSwizzle(const Swizzle& swizzle, std::ostream& out);
|
||||
SpvId writeSwizzle(const Swizzle& swizzle, SkWStream& out);
|
||||
|
||||
SpvId writeBinaryOperation(const Type& resultType, const Type& operandType, SpvId lhs,
|
||||
SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ ifUInt,
|
||||
SpvOp_ ifBool, std::ostream& out);
|
||||
SpvOp_ ifBool, SkWStream& out);
|
||||
|
||||
SpvId writeBinaryOperation(const BinaryExpression& expr, SpvOp_ ifFloat, SpvOp_ ifInt,
|
||||
SpvOp_ ifUInt, std::ostream& out);
|
||||
SpvOp_ ifUInt, SkWStream& out);
|
||||
|
||||
SpvId writeBinaryExpression(const BinaryExpression& b, std::ostream& out);
|
||||
SpvId writeBinaryExpression(const BinaryExpression& b, SkWStream& out);
|
||||
|
||||
SpvId writeTernaryExpression(const TernaryExpression& t, std::ostream& out);
|
||||
SpvId writeTernaryExpression(const TernaryExpression& t, SkWStream& out);
|
||||
|
||||
SpvId writeIndexExpression(const IndexExpression& expr, std::ostream& out);
|
||||
SpvId writeIndexExpression(const IndexExpression& expr, SkWStream& out);
|
||||
|
||||
SpvId writeLogicalAnd(const BinaryExpression& b, std::ostream& out);
|
||||
SpvId writeLogicalAnd(const BinaryExpression& b, SkWStream& out);
|
||||
|
||||
SpvId writeLogicalOr(const BinaryExpression& o, std::ostream& out);
|
||||
SpvId writeLogicalOr(const BinaryExpression& o, SkWStream& out);
|
||||
|
||||
SpvId writePrefixExpression(const PrefixExpression& p, std::ostream& out);
|
||||
SpvId writePrefixExpression(const PrefixExpression& p, SkWStream& out);
|
||||
|
||||
SpvId writePostfixExpression(const PostfixExpression& p, std::ostream& out);
|
||||
SpvId writePostfixExpression(const PostfixExpression& p, SkWStream& out);
|
||||
|
||||
SpvId writeBoolLiteral(const BoolLiteral& b);
|
||||
|
||||
@ -174,59 +174,59 @@ private:
|
||||
|
||||
SpvId writeFloatLiteral(const FloatLiteral& f);
|
||||
|
||||
void writeStatement(const Statement& s, std::ostream& out);
|
||||
void writeStatement(const Statement& s, SkWStream& out);
|
||||
|
||||
void writeBlock(const Block& b, std::ostream& out);
|
||||
void writeBlock(const Block& b, SkWStream& out);
|
||||
|
||||
void writeIfStatement(const IfStatement& stmt, std::ostream& out);
|
||||
void writeIfStatement(const IfStatement& stmt, SkWStream& out);
|
||||
|
||||
void writeForStatement(const ForStatement& f, std::ostream& out);
|
||||
void writeForStatement(const ForStatement& f, SkWStream& out);
|
||||
|
||||
void writeReturnStatement(const ReturnStatement& r, std::ostream& out);
|
||||
void writeReturnStatement(const ReturnStatement& r, SkWStream& out);
|
||||
|
||||
void writeCapabilities(std::ostream& out);
|
||||
void writeCapabilities(SkWStream& out);
|
||||
|
||||
void writeInstructions(const Program& program, std::ostream& out);
|
||||
void writeInstructions(const Program& program, SkWStream& out);
|
||||
|
||||
void writeOpCode(SpvOp_ opCode, int length, std::ostream& out);
|
||||
void writeOpCode(SpvOp_ opCode, int length, SkWStream& out);
|
||||
|
||||
void writeWord(int32_t word, std::ostream& out);
|
||||
void writeWord(int32_t word, SkWStream& out);
|
||||
|
||||
void writeString(const char* string, std::ostream& out);
|
||||
void writeString(const char* string, SkWStream& out);
|
||||
|
||||
void writeLabel(SpvId id, std::ostream& out);
|
||||
void writeLabel(SpvId id, SkWStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, std::ostream& out);
|
||||
void writeInstruction(SpvOp_ opCode, SkWStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, const char* string, std::ostream& out);
|
||||
void writeInstruction(SpvOp_ opCode, const char* string, SkWStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, std::ostream& out);
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, SkWStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, const char* string, std::ostream& out);
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, const char* string, SkWStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, const char* string,
|
||||
std::ostream& out);
|
||||
SkWStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, std::ostream& out);
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, SkWStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3,
|
||||
std::ostream& out);
|
||||
SkWStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
|
||||
std::ostream& out);
|
||||
SkWStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
|
||||
int32_t word5, std::ostream& out);
|
||||
int32_t word5, SkWStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
|
||||
int32_t word5, int32_t word6, std::ostream& out);
|
||||
int32_t word5, int32_t word6, SkWStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
|
||||
int32_t word5, int32_t word6, int32_t word7, std::ostream& out);
|
||||
int32_t word5, int32_t word6, int32_t word7, SkWStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
|
||||
int32_t word5, int32_t word6, int32_t word7, int32_t word8,
|
||||
std::ostream& out);
|
||||
SkWStream& out);
|
||||
|
||||
const Context& fContext;
|
||||
|
||||
@ -234,18 +234,18 @@ private:
|
||||
SpvId fIdCount;
|
||||
SpvId fGLSLExtendedInstructions;
|
||||
typedef std::tuple<IntrinsicKind, int32_t, int32_t, int32_t, int32_t> Intrinsic;
|
||||
std::unordered_map<std::string, Intrinsic> fIntrinsicMap;
|
||||
std::unordered_map<SkString, Intrinsic> fIntrinsicMap;
|
||||
std::unordered_map<const FunctionDeclaration*, SpvId> fFunctionMap;
|
||||
std::unordered_map<const Variable*, SpvId> fVariableMap;
|
||||
std::unordered_map<const Variable*, int32_t> fInterfaceBlockMap;
|
||||
std::unordered_map<std::string, SpvId> fTypeMap;
|
||||
std::stringstream fCapabilitiesBuffer;
|
||||
std::stringstream fGlobalInitializersBuffer;
|
||||
std::stringstream fConstantBuffer;
|
||||
std::stringstream fExternalFunctionsBuffer;
|
||||
std::stringstream fVariableBuffer;
|
||||
std::stringstream fNameBuffer;
|
||||
std::stringstream fDecorationBuffer;
|
||||
std::unordered_map<SkString, SpvId> fTypeMap;
|
||||
SkDynamicMemoryWStream fCapabilitiesBuffer;
|
||||
SkDynamicMemoryWStream fGlobalInitializersBuffer;
|
||||
SkDynamicMemoryWStream fConstantBuffer;
|
||||
SkDynamicMemoryWStream fExternalFunctionsBuffer;
|
||||
SkDynamicMemoryWStream fVariableBuffer;
|
||||
SkDynamicMemoryWStream fNameBuffer;
|
||||
SkDynamicMemoryWStream fDecorationBuffer;
|
||||
|
||||
SpvId fBoolTrue;
|
||||
SpvId fBoolFalse;
|
||||
|
@ -103,45 +103,45 @@ struct Token {
|
||||
INVALID_TOKEN
|
||||
};
|
||||
|
||||
static std::string OperatorName(Kind kind) {
|
||||
static SkString OperatorName(Kind kind) {
|
||||
switch (kind) {
|
||||
case Token::PLUS: return "+";
|
||||
case Token::MINUS: return "-";
|
||||
case Token::STAR: return "*";
|
||||
case Token::SLASH: return "/";
|
||||
case Token::PERCENT: return "%";
|
||||
case Token::SHL: return "<<";
|
||||
case Token::SHR: return ">>";
|
||||
case Token::LOGICALNOT: return "!";
|
||||
case Token::LOGICALAND: return "&&";
|
||||
case Token::LOGICALOR: return "||";
|
||||
case Token::LOGICALXOR: return "^^";
|
||||
case Token::BITWISENOT: return "~";
|
||||
case Token::BITWISEAND: return "&";
|
||||
case Token::BITWISEOR: return "|";
|
||||
case Token::BITWISEXOR: return "^";
|
||||
case Token::EQ: return "=";
|
||||
case Token::EQEQ: return "==";
|
||||
case Token::NEQ: return "!=";
|
||||
case Token::LT: return "<";
|
||||
case Token::GT: return ">";
|
||||
case Token::LTEQ: return "<=";
|
||||
case Token::GTEQ: return ">=";
|
||||
case Token::PLUSEQ: return "+=";
|
||||
case Token::MINUSEQ: return "-=";
|
||||
case Token::STAREQ: return "*=";
|
||||
case Token::SLASHEQ: return "/=";
|
||||
case Token::PERCENTEQ: return "%=";
|
||||
case Token::SHLEQ: return "<<=";
|
||||
case Token::SHREQ: return ">>=";
|
||||
case Token::LOGICALANDEQ: return "&&=";
|
||||
case Token::LOGICALOREQ: return "||=";
|
||||
case Token::LOGICALXOREQ: return "^^=";
|
||||
case Token::BITWISEANDEQ: return "&=";
|
||||
case Token::BITWISEOREQ: return "|=";
|
||||
case Token::BITWISEXOREQ: return "^=";
|
||||
case Token::PLUSPLUS: return "++";
|
||||
case Token::MINUSMINUS: return "--";
|
||||
case Token::PLUS: return SkString("+");
|
||||
case Token::MINUS: return SkString("-");
|
||||
case Token::STAR: return SkString("*");
|
||||
case Token::SLASH: return SkString("/");
|
||||
case Token::PERCENT: return SkString("%");
|
||||
case Token::SHL: return SkString("<<");
|
||||
case Token::SHR: return SkString(">>");
|
||||
case Token::LOGICALNOT: return SkString("!");
|
||||
case Token::LOGICALAND: return SkString("&&");
|
||||
case Token::LOGICALOR: return SkString("||");
|
||||
case Token::LOGICALXOR: return SkString("^^");
|
||||
case Token::BITWISENOT: return SkString("~");
|
||||
case Token::BITWISEAND: return SkString("&");
|
||||
case Token::BITWISEOR: return SkString("|");
|
||||
case Token::BITWISEXOR: return SkString("^");
|
||||
case Token::EQ: return SkString("=");
|
||||
case Token::EQEQ: return SkString("==");
|
||||
case Token::NEQ: return SkString("!=");
|
||||
case Token::LT: return SkString("<");
|
||||
case Token::GT: return SkString(">");
|
||||
case Token::LTEQ: return SkString("<=");
|
||||
case Token::GTEQ: return SkString(">=");
|
||||
case Token::PLUSEQ: return SkString("+=");
|
||||
case Token::MINUSEQ: return SkString("-=");
|
||||
case Token::STAREQ: return SkString("*=");
|
||||
case Token::SLASHEQ: return SkString("/=");
|
||||
case Token::PERCENTEQ: return SkString("%=");
|
||||
case Token::SHLEQ: return SkString("<<=");
|
||||
case Token::SHREQ: return SkString(">>=");
|
||||
case Token::LOGICALANDEQ: return SkString("&&=");
|
||||
case Token::LOGICALOREQ: return SkString("||=");
|
||||
case Token::LOGICALXOREQ: return SkString("^^=");
|
||||
case Token::BITWISEANDEQ: return SkString("&=");
|
||||
case Token::BITWISEOREQ: return SkString("|=");
|
||||
case Token::BITWISEXOREQ: return SkString("^=");
|
||||
case Token::PLUSPLUS: return SkString("++");
|
||||
case Token::MINUSMINUS: return SkString("--");
|
||||
default:
|
||||
ABORT("unsupported operator: %d\n", kind);
|
||||
}
|
||||
@ -150,7 +150,7 @@ struct Token {
|
||||
Token() {
|
||||
}
|
||||
|
||||
Token(Position position, Kind kind, std::string text)
|
||||
Token(Position position, Kind kind, SkString text)
|
||||
: fPosition(position)
|
||||
, fKind(kind)
|
||||
, fText(std::move(text)) {}
|
||||
@ -159,7 +159,7 @@ struct Token {
|
||||
Kind fKind;
|
||||
// will be the empty string unless the token has variable text content (identifiers, numeric
|
||||
// literals, and directives)
|
||||
std::string fText;
|
||||
SkString fText;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -7,61 +7,66 @@
|
||||
|
||||
#include "SkSLUtil.h"
|
||||
|
||||
#ifndef __STDC_FORMAT_MACROS
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
#include <cinttypes>
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
std::string to_string(double value) {
|
||||
std::stringstream buffer;
|
||||
buffer << std::setprecision(std::numeric_limits<double>::digits10) << value;
|
||||
std::string result = buffer.str();
|
||||
if (result.find_last_of(".") == std::string::npos &&
|
||||
result.find_last_of("e") == std::string::npos) {
|
||||
SkString to_string(double value) {
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
#define SNPRINTF _snprintf
|
||||
#else
|
||||
#define SNPRINTF snprintf
|
||||
#endif
|
||||
#define MAX_DOUBLE_CHARS 25
|
||||
char buffer[MAX_DOUBLE_CHARS];
|
||||
SkDEBUGCODE(int len = )SNPRINTF(buffer, sizeof(buffer), "%.17g", value);
|
||||
ASSERT(len < MAX_DOUBLE_CHARS);
|
||||
SkString result(buffer);
|
||||
if (!strchr(buffer, '.') && !strchr(buffer, 'e')) {
|
||||
result += ".0";
|
||||
}
|
||||
return result;
|
||||
#undef SNPRINTF
|
||||
#undef MAX_DOUBLE_CHARS
|
||||
}
|
||||
|
||||
std::string to_string(int32_t value) {
|
||||
std::stringstream buffer;
|
||||
buffer << value;
|
||||
return buffer.str();
|
||||
SkString to_string(int32_t value) {
|
||||
return SkStringPrintf("%d", value);
|
||||
}
|
||||
|
||||
std::string to_string(uint32_t value) {
|
||||
std::stringstream buffer;
|
||||
buffer << value;
|
||||
return buffer.str();
|
||||
SkString to_string(uint32_t value) {
|
||||
return SkStringPrintf("%u", value);
|
||||
}
|
||||
|
||||
std::string to_string(int64_t value) {
|
||||
std::stringstream buffer;
|
||||
buffer << value;
|
||||
return buffer.str();
|
||||
SkString to_string(int64_t value) {
|
||||
return SkStringPrintf("%" PRId64, value);
|
||||
}
|
||||
|
||||
std::string to_string(uint64_t value) {
|
||||
std::stringstream buffer;
|
||||
buffer << value;
|
||||
return buffer.str();
|
||||
SkString to_string(uint64_t value) {
|
||||
return SkStringPrintf("%" PRIu64, value);
|
||||
}
|
||||
|
||||
int stoi(std::string s) {
|
||||
int stoi(SkString s) {
|
||||
if (s.size() > 2 && s[0] == '0' && s[1] == 'x') {
|
||||
char* p;
|
||||
int result = strtoul(s.substr(2).c_str(), &p, 16);
|
||||
int result = strtoul(s.c_str() + 2, &p, 16);
|
||||
ASSERT(*p == 0);
|
||||
return result;
|
||||
}
|
||||
return atoi(s.c_str());
|
||||
}
|
||||
|
||||
double stod(std::string s) {
|
||||
double stod(SkString s) {
|
||||
return atof(s.c_str());
|
||||
}
|
||||
|
||||
long stol(std::string s) {
|
||||
long stol(SkString s) {
|
||||
if (s.size() > 2 && s[0] == '0' && s[1] == 'x') {
|
||||
char* p;
|
||||
long result = strtoul(s.substr(2).c_str(), &p, 16);
|
||||
long result = strtoul(s.c_str() + 2, &p, 16);
|
||||
ASSERT(*p == 0);
|
||||
return result;
|
||||
}
|
||||
@ -77,4 +82,37 @@ void sksl_abort() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void write_data(const SkData& data, SkWStream& out) {
|
||||
out.write(data.data(), data.size());
|
||||
}
|
||||
|
||||
SkString operator+(const SkString& s, const char* c) {
|
||||
SkString result(s);
|
||||
result += c;
|
||||
return result;
|
||||
}
|
||||
|
||||
SkString operator+(const char* c, const SkString& s) {
|
||||
SkString result(c);
|
||||
result += s;
|
||||
return result;
|
||||
}
|
||||
|
||||
SkString operator+(const SkString& s1, const SkString& s2) {
|
||||
SkString result(s1);
|
||||
result += s2;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool operator==(const SkString& s1, const char* s2) {
|
||||
return !strcmp(s1.c_str(), s2);
|
||||
}
|
||||
|
||||
bool operator!=(const SkString& s1, const char* s2) {
|
||||
return strcmp(s1.c_str(), s2);
|
||||
}
|
||||
|
||||
bool operator!=(const char* s1, const SkString& s2) {
|
||||
return strcmp(s1, s2.c_str());
|
||||
}
|
||||
} // namespace
|
||||
|
@ -8,12 +8,12 @@
|
||||
#ifndef SKSL_UTIL
|
||||
#define SKSL_UTIL
|
||||
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "stdlib.h"
|
||||
#include "assert.h"
|
||||
#include "SkOpts.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkString.h"
|
||||
#include "SkTypes.h"
|
||||
#include "glsl/GrGLSLCaps.h"
|
||||
#include "GrContextOptions.h"
|
||||
@ -73,40 +73,47 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// our own definitions of certain std:: functions, because they are not always present on Android
|
||||
void write_data(const SkData& d, SkWStream& out);
|
||||
|
||||
std::string to_string(double value);
|
||||
SkString operator+(const SkString& s, const char* c);
|
||||
|
||||
std::string to_string(int32_t value);
|
||||
SkString operator+(const char* c, const SkString& s);
|
||||
|
||||
std::string to_string(uint32_t value);
|
||||
SkString operator+(const SkString& s1, const SkString& s2);
|
||||
|
||||
std::string to_string(int64_t value);
|
||||
bool operator==(const SkString& s1, const char* s2);
|
||||
|
||||
std::string to_string(uint64_t value);
|
||||
bool operator!=(const SkString& s1, const char* s2);
|
||||
|
||||
bool operator!=(const char* s1, const SkString& s2);
|
||||
|
||||
SkString to_string(double value);
|
||||
|
||||
SkString to_string(int32_t value);
|
||||
|
||||
SkString to_string(uint32_t value);
|
||||
|
||||
SkString to_string(int64_t value);
|
||||
|
||||
SkString to_string(uint64_t value);
|
||||
|
||||
#if _MSC_VER
|
||||
#define NORETURN __declspec(noreturn)
|
||||
#else
|
||||
#define NORETURN __attribute__((__noreturn__))
|
||||
#endif
|
||||
int stoi(std::string s);
|
||||
int stoi(SkString s);
|
||||
|
||||
double stod(std::string s);
|
||||
double stod(SkString s);
|
||||
|
||||
long stol(std::string s);
|
||||
long stol(SkString s);
|
||||
|
||||
NORETURN void sksl_abort();
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef DEBUG
|
||||
#define ASSERT(x) assert(x)
|
||||
#define ASSERT_RESULT(x) ASSERT(x);
|
||||
#else
|
||||
#define ASSERT(x)
|
||||
#define ASSERT_RESULT(x) x
|
||||
#endif
|
||||
#define ASSERT(x) SkASSERT(x)
|
||||
#define ASSERT_RESULT(x) SkAssertResult(x);
|
||||
|
||||
#ifdef SKIA
|
||||
#define ABORT(...) { SkDebugf(__VA_ARGS__); sksl_abort(); }
|
||||
@ -114,4 +121,11 @@ NORETURN void sksl_abort();
|
||||
#define ABORT(...) { sksl_abort(); }
|
||||
#endif
|
||||
|
||||
namespace std {
|
||||
template<> struct hash<SkString> {
|
||||
size_t operator()(const SkString& s) const {
|
||||
return SkOpts::hash_fn(s.c_str(), s.size(), 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "SkSLASTExpression.h"
|
||||
#include "../SkSLToken.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
@ -25,7 +24,7 @@ struct ASTBinaryExpression : public ASTExpression {
|
||||
, fOperator(op.fKind)
|
||||
, fRight(std::move(right)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return "(" + fLeft->description() + " " + Token::OperatorName(fOperator) + " " +
|
||||
fRight->description() + ")";
|
||||
}
|
||||
|
@ -20,8 +20,8 @@ struct ASTBlock : public ASTStatement {
|
||||
: INHERITED(position, kBlock_Kind)
|
||||
, fStatements(std::move(statements)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result("{");
|
||||
SkString description() const override {
|
||||
SkString result("{");
|
||||
for (size_t i = 0; i < fStatements.size(); i++) {
|
||||
result += "\n";
|
||||
result += fStatements[i]->description();
|
||||
|
@ -20,8 +20,8 @@ struct ASTBoolLiteral : public ASTExpression {
|
||||
: INHERITED(position, kBool_Kind)
|
||||
, fValue(value) {}
|
||||
|
||||
std::string description() const override {
|
||||
return fValue ? "true" : "false";
|
||||
SkString description() const override {
|
||||
return SkString(fValue ? "true" : "false");
|
||||
}
|
||||
|
||||
const bool fValue;
|
||||
|
@ -19,8 +19,8 @@ struct ASTBreakStatement : public ASTStatement {
|
||||
ASTBreakStatement(Position position)
|
||||
: INHERITED(position, kBreak_Kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "break;";
|
||||
SkString description() const override {
|
||||
return SkString("break;");
|
||||
}
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
|
@ -8,7 +8,6 @@
|
||||
#ifndef SKSL_ASTCALLSUFFIX
|
||||
#define SKSL_ASTCALLSUFFIX
|
||||
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include "SkSLASTSuffix.h"
|
||||
|
||||
@ -22,9 +21,9 @@ struct ASTCallSuffix : public ASTSuffix {
|
||||
: INHERITED(position, ASTSuffix::kCall_Kind)
|
||||
, fArguments(std::move(arguments)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result("(");
|
||||
std::string separator = "";
|
||||
SkString description() const override {
|
||||
SkString result("(");
|
||||
SkString separator;
|
||||
for (size_t i = 0; i < fArguments.size(); ++i) {
|
||||
result += separator;
|
||||
separator = ", ";
|
||||
|
@ -19,8 +19,8 @@ struct ASTContinueStatement : public ASTStatement {
|
||||
ASTContinueStatement(Position position)
|
||||
: INHERITED(position, kContinue_Kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "continue;";
|
||||
SkString description() const override {
|
||||
return SkString("continue;");
|
||||
}
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
|
@ -19,8 +19,8 @@ struct ASTDiscardStatement : public ASTStatement {
|
||||
ASTDiscardStatement(Position position)
|
||||
: INHERITED(position, kDiscard_Kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "discard;";
|
||||
SkString description() const override {
|
||||
return SkString("discard;");
|
||||
}
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
|
@ -22,7 +22,7 @@ struct ASTDoStatement : public ASTStatement {
|
||||
, fStatement(std::move(statement))
|
||||
, fTest(std::move(test)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return "do " + fStatement->description() + " while (" + fTest->description() + ");";
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ struct ASTExpressionStatement : public ASTStatement {
|
||||
: INHERITED(expression->fPosition, kExpression_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return fExpression->description() + ";";
|
||||
}
|
||||
|
||||
|
@ -16,15 +16,15 @@ namespace SkSL {
|
||||
* An extension declaration.
|
||||
*/
|
||||
struct ASTExtension : public ASTDeclaration {
|
||||
ASTExtension(Position position, std::string name)
|
||||
ASTExtension(Position position, SkString name)
|
||||
: INHERITED(position, kExtension_Kind)
|
||||
, fName(std::move(name)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return "#extension " + fName + " : enable";
|
||||
}
|
||||
|
||||
const std::string fName;
|
||||
const SkString fName;
|
||||
|
||||
typedef ASTDeclaration INHERITED;
|
||||
};
|
||||
|
@ -17,15 +17,15 @@ namespace SkSL {
|
||||
* actually vector swizzle (which looks the same to the parser).
|
||||
*/
|
||||
struct ASTFieldSuffix : public ASTSuffix {
|
||||
ASTFieldSuffix(Position position, std::string field)
|
||||
ASTFieldSuffix(Position position, SkString field)
|
||||
: INHERITED(position, ASTSuffix::kField_Kind)
|
||||
, fField(std::move(field)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return "." + fField;
|
||||
}
|
||||
|
||||
std::string fField;
|
||||
SkString fField;
|
||||
|
||||
typedef ASTSuffix INHERITED;
|
||||
};
|
||||
|
@ -20,7 +20,7 @@ struct ASTFloatLiteral : public ASTExpression {
|
||||
: INHERITED(position, kFloat_Kind)
|
||||
, fValue(value) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return to_string(fValue);
|
||||
}
|
||||
|
||||
|
@ -25,8 +25,8 @@ struct ASTForStatement : public ASTStatement {
|
||||
, fNext(std::move(next))
|
||||
, fStatement(std::move(statement)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = "for (";
|
||||
SkString description() const override {
|
||||
SkString result("for (");
|
||||
if (fInitializer) {
|
||||
result.append(fInitializer->description());
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ namespace SkSL {
|
||||
* A function declaration or definition. The fBody field will be null for declarations.
|
||||
*/
|
||||
struct ASTFunction : public ASTDeclaration {
|
||||
ASTFunction(Position position, std::unique_ptr<ASTType> returnType, std::string name,
|
||||
ASTFunction(Position position, std::unique_ptr<ASTType> returnType, SkString name,
|
||||
std::vector<std::unique_ptr<ASTParameter>> parameters,
|
||||
std::unique_ptr<ASTBlock> body)
|
||||
: INHERITED(position, kFunction_Kind)
|
||||
@ -28,8 +28,8 @@ struct ASTFunction : public ASTDeclaration {
|
||||
, fParameters(std::move(parameters))
|
||||
, fBody(std::move(body)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fReturnType->description() + " " + fName + "(";
|
||||
SkString description() const override {
|
||||
SkString result = fReturnType->description() + " " + fName + "(";
|
||||
for (size_t i = 0; i < fParameters.size(); i++) {
|
||||
if (i > 0) {
|
||||
result += ", ";
|
||||
@ -45,7 +45,7 @@ struct ASTFunction : public ASTDeclaration {
|
||||
}
|
||||
|
||||
const std::unique_ptr<ASTType> fReturnType;
|
||||
const std::string fName;
|
||||
const SkString fName;
|
||||
const std::vector<std::unique_ptr<ASTParameter>> fParameters;
|
||||
const std::unique_ptr<ASTBlock> fBody;
|
||||
|
||||
|
@ -16,15 +16,15 @@ namespace SkSL {
|
||||
* An identifier in an expression context.
|
||||
*/
|
||||
struct ASTIdentifier : public ASTExpression {
|
||||
ASTIdentifier(Position position, std::string text)
|
||||
ASTIdentifier(Position position, SkString text)
|
||||
: INHERITED(position, kIdentifier_Kind)
|
||||
, fText(std::move(text)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return fText;
|
||||
}
|
||||
|
||||
const std::string fText;
|
||||
const SkString fText;
|
||||
|
||||
typedef ASTExpression INHERITED;
|
||||
};
|
||||
|
@ -23,8 +23,8 @@ struct ASTIfStatement : public ASTStatement {
|
||||
, fIfTrue(std::move(ifTrue))
|
||||
, fIfFalse(std::move(ifFalse)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result("if (");
|
||||
SkString description() const override {
|
||||
SkString result("if (");
|
||||
result += fTest->description();
|
||||
result += ") ";
|
||||
result += fIfTrue->description();
|
||||
|
@ -26,11 +26,11 @@ struct ASTIndexSuffix : public ASTSuffix {
|
||||
: INHERITED(expression ? expression->fPosition : Position(), ASTSuffix::kIndex_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
if (fExpression) {
|
||||
return "[" + fExpression->description() + "]";
|
||||
} else {
|
||||
return "[]";
|
||||
return SkString("[]");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ struct ASTIntLiteral : public ASTExpression {
|
||||
: INHERITED(position, kInt_Kind)
|
||||
, fValue(value) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return to_string(fValue);
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,8 @@ struct ASTInterfaceBlock : public ASTDeclaration {
|
||||
// valueName is empty when it was not present in the source
|
||||
ASTInterfaceBlock(Position position,
|
||||
ASTModifiers modifiers,
|
||||
std::string interfaceName,
|
||||
std::string valueName,
|
||||
SkString interfaceName,
|
||||
SkString valueName,
|
||||
std::vector<std::unique_ptr<ASTVarDeclarations>> declarations)
|
||||
: INHERITED(position, kInterfaceBlock_Kind)
|
||||
, fModifiers(modifiers)
|
||||
@ -33,21 +33,21 @@ struct ASTInterfaceBlock : public ASTDeclaration {
|
||||
, fValueName(std::move(valueName))
|
||||
, fDeclarations(std::move(declarations)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fModifiers.description() + fInterfaceName + " {\n";
|
||||
SkString description() const override {
|
||||
SkString result = fModifiers.description() + fInterfaceName + " {\n";
|
||||
for (size_t i = 0; i < fDeclarations.size(); i++) {
|
||||
result += fDeclarations[i]->description() + "\n";
|
||||
}
|
||||
result += "}";
|
||||
if (fValueName.length()) {
|
||||
if (fValueName.size()) {
|
||||
result += " " + fValueName;
|
||||
}
|
||||
return result + ";";
|
||||
}
|
||||
|
||||
const ASTModifiers fModifiers;
|
||||
const std::string fInterfaceName;
|
||||
const std::string fValueName;
|
||||
const SkString fInterfaceName;
|
||||
const SkString fValueName;
|
||||
const std::vector<std::unique_ptr<ASTVarDeclarations>> fDeclarations;
|
||||
|
||||
typedef ASTDeclaration INHERITED;
|
||||
|
@ -48,7 +48,7 @@ struct ASTLayout : public ASTNode {
|
||||
return "";
|
||||
}
|
||||
|
||||
static bool ReadFormat(std::string str, Format* format) {
|
||||
static bool ReadFormat(SkString str, Format* format) {
|
||||
if (str == "rgba32f") {
|
||||
*format = Format::kRGBA32F;
|
||||
return true;
|
||||
@ -90,9 +90,9 @@ struct ASTLayout : public ASTNode {
|
||||
, fBlendSupportAllEquations(blendSupportAllEquations)
|
||||
, fFormat(format) {}
|
||||
|
||||
std::string description() const {
|
||||
std::string result;
|
||||
std::string separator;
|
||||
SkString description() const {
|
||||
SkString result;
|
||||
SkString separator;
|
||||
if (fLocation >= 0) {
|
||||
result += separator + "location = " + to_string(fLocation);
|
||||
separator = ", ";
|
||||
@ -129,7 +129,7 @@ struct ASTLayout : public ASTNode {
|
||||
result += separator + FormatToStr(fFormat);
|
||||
separator = ", ";
|
||||
}
|
||||
if (result.length() > 0) {
|
||||
if (result.size() > 0) {
|
||||
result = "layout (" + result + ")";
|
||||
}
|
||||
return result;
|
||||
|
@ -34,8 +34,8 @@ struct ASTModifiers : public ASTNode {
|
||||
: fLayout(layout)
|
||||
, fFlags(flags) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fLayout.description();
|
||||
SkString description() const override {
|
||||
SkString result = fLayout.description();
|
||||
if (fFlags & kUniform_Flag) {
|
||||
result += "uniform ";
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ struct ASTModifiersDeclaration : public ASTDeclaration {
|
||||
: INHERITED(Position(), kModifiers_Kind)
|
||||
, fModifiers(modifiers) {}
|
||||
|
||||
std::string description() const {
|
||||
SkString description() const {
|
||||
return fModifiers.description() + ";";
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,7 @@
|
||||
#ifndef SKSL_ASTNODE
|
||||
#define SKSL_ASTNODE
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "SkString.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
@ -20,7 +19,7 @@ namespace SkSL {
|
||||
struct ASTNode {
|
||||
virtual ~ASTNode() {}
|
||||
|
||||
virtual std::string description() const = 0;
|
||||
virtual SkString description() const = 0;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -20,15 +20,15 @@ struct ASTParameter : public ASTPositionNode {
|
||||
// 'sizes' is a list of the array sizes appearing on a parameter, in source order.
|
||||
// e.g. int x[3][1] would have sizes [3, 1].
|
||||
ASTParameter(Position position, ASTModifiers modifiers, std::unique_ptr<ASTType> type,
|
||||
std::string name, std::vector<int> sizes)
|
||||
SkString name, std::vector<int> sizes)
|
||||
: INHERITED(position)
|
||||
, fModifiers(modifiers)
|
||||
, fType(std::move(type))
|
||||
, fName(std::move(name))
|
||||
, fSizes(std::move(sizes)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fModifiers.description() + fType->description() + " " + fName;
|
||||
SkString description() const override {
|
||||
SkString result = fModifiers.description() + fType->description() + " " + fName;
|
||||
for (int size : fSizes) {
|
||||
result += "[" + to_string(size) + "]";
|
||||
}
|
||||
@ -37,7 +37,7 @@ struct ASTParameter : public ASTPositionNode {
|
||||
|
||||
const ASTModifiers fModifiers;
|
||||
const std::unique_ptr<ASTType> fType;
|
||||
const std::string fName;
|
||||
const SkString fName;
|
||||
const std::vector<int> fSizes;
|
||||
|
||||
typedef ASTPositionNode INHERITED;
|
||||
|
@ -22,17 +22,17 @@ struct ASTPrecision : public ASTDeclaration {
|
||||
: INHERITED(position, kPrecision_Kind)
|
||||
, fPrecision(precision) {}
|
||||
|
||||
std::string description() const {
|
||||
SkString description() const {
|
||||
switch (fPrecision) {
|
||||
case Modifiers::kLowp_Flag: return "precision lowp float;";
|
||||
case Modifiers::kMediump_Flag: return "precision mediump float;";
|
||||
case Modifiers::kHighp_Flag: return "precision highp float;";
|
||||
case Modifiers::kLowp_Flag: return SkString("precision lowp float;");
|
||||
case Modifiers::kMediump_Flag: return SkString("precision mediump float;");
|
||||
case Modifiers::kHighp_Flag: return SkString("precision highp float;");
|
||||
default:
|
||||
ASSERT(false);
|
||||
return "<error>";
|
||||
return SkString("<error>");
|
||||
}
|
||||
ASSERT(false);
|
||||
return "<error>";
|
||||
return SkString("<error>");
|
||||
}
|
||||
|
||||
const Modifiers::Flag fPrecision;
|
||||
|
@ -22,7 +22,7 @@ struct ASTPrefixExpression : public ASTExpression {
|
||||
, fOperator(op.fKind)
|
||||
, fOperand(std::move(operand)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return Token::OperatorName(fOperator) + fOperand->description();
|
||||
}
|
||||
|
||||
|
@ -21,8 +21,8 @@ struct ASTReturnStatement : public ASTStatement {
|
||||
: INHERITED(position, kReturn_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result("return");
|
||||
SkString description() const override {
|
||||
SkString result("return");
|
||||
if (fExpression) {
|
||||
result += " " + fExpression->description();
|
||||
}
|
||||
|
@ -30,12 +30,12 @@ struct ASTSuffix : public ASTPositionNode {
|
||||
: INHERITED(position)
|
||||
, fKind(kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
switch (fKind) {
|
||||
case kPostIncrement_Kind:
|
||||
return "++";
|
||||
return SkString("++");
|
||||
case kPostDecrement_Kind:
|
||||
return "--";
|
||||
return SkString("--");
|
||||
default:
|
||||
ABORT("unsupported suffix operator");
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ struct ASTSuffixExpression : public ASTExpression {
|
||||
, fBase(std::move(base))
|
||||
, fSuffix(std::move(suffix)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return fBase->description() + fSuffix->description();
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ struct ASTTernaryExpression : public ASTExpression {
|
||||
, fIfTrue(std::move(ifTrue))
|
||||
, fIfFalse(std::move(ifFalse)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return "(" + fTest->description() + " ? " + fIfTrue->description() + " : " +
|
||||
fIfFalse->description() + ")";
|
||||
}
|
||||
|
@ -19,16 +19,16 @@ struct ASTType : public ASTPositionNode {
|
||||
kStruct_Kind
|
||||
};
|
||||
|
||||
ASTType(Position position, std::string name, Kind kind)
|
||||
ASTType(Position position, SkString name, Kind kind)
|
||||
: INHERITED(position)
|
||||
, fName(std::move(name))
|
||||
, fKind(kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return fName;
|
||||
}
|
||||
|
||||
const std::string fName;
|
||||
const SkString fName;
|
||||
|
||||
const Kind fKind;
|
||||
|
||||
|
@ -22,15 +22,15 @@ namespace SkSL {
|
||||
* instances.
|
||||
*/
|
||||
struct ASTVarDeclaration {
|
||||
ASTVarDeclaration(const std::string name,
|
||||
ASTVarDeclaration(const SkString name,
|
||||
std::vector<std::unique_ptr<ASTExpression>> sizes,
|
||||
std::unique_ptr<ASTExpression> value)
|
||||
: fName(name)
|
||||
, fSizes(std::move(sizes))
|
||||
, fValue(std::move(value)) {}
|
||||
|
||||
std::string description() const {
|
||||
std::string result = fName;
|
||||
SkString description() const {
|
||||
SkString result = fName;
|
||||
for (const auto& size : fSizes) {
|
||||
if (size) {
|
||||
result += "[" + size->description() + "]";
|
||||
@ -44,7 +44,7 @@ struct ASTVarDeclaration {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string fName;
|
||||
SkString fName;
|
||||
|
||||
// array sizes, if any. e.g. 'foo[3][]' has sizes [3, null]
|
||||
std::vector<std::unique_ptr<ASTExpression>> fSizes;
|
||||
@ -65,9 +65,9 @@ struct ASTVarDeclarations : public ASTDeclaration {
|
||||
, fType(std::move(type))
|
||||
, fVars(std::move(vars)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fModifiers.description() + fType->description() + " ";
|
||||
std::string separator = "";
|
||||
SkString description() const override {
|
||||
SkString result = fModifiers.description() + fType->description() + " ";
|
||||
SkString separator;
|
||||
for (const auto& var : fVars) {
|
||||
result += separator;
|
||||
separator = ", ";
|
||||
|
@ -21,7 +21,7 @@ struct ASTVarDeclarationStatement : public ASTStatement {
|
||||
: INHERITED(decl->fPosition, kVarDeclaration_Kind)
|
||||
, fDeclarations(std::move(decl)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return fDeclarations->description() + ";";
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ struct ASTWhileStatement : public ASTStatement {
|
||||
, fTest(std::move(test))
|
||||
, fStatement(std::move(statement)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return "while (" + fTest->description() + ") " + fStatement->description();
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ struct BinaryExpression : public Expression {
|
||||
, fOperator(op)
|
||||
, fRight(std::move(right)) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
virtual SkString description() const override {
|
||||
return "(" + fLeft->description() + " " + Token::OperatorName(fOperator) + " " +
|
||||
fRight->description() + ")";
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SKSL_BLOCK
|
||||
#define SKSL_BLOCK
|
||||
|
||||
@ -23,14 +23,14 @@ struct Block : public Statement {
|
||||
, fStatements(std::move(statements))
|
||||
, fSymbols(std::move(symbols)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = "{";
|
||||
SkString description() const override {
|
||||
SkString result("{");
|
||||
for (size_t i = 0; i < fStatements.size(); i++) {
|
||||
result += "\n";
|
||||
result += fStatements[i]->description();
|
||||
}
|
||||
result += "\n}\n";
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<Statement>> fStatements;
|
||||
|
@ -21,8 +21,8 @@ struct BoolLiteral : public Expression {
|
||||
: INHERITED(position, kBoolLiteral_Kind, *context.fBool_Type)
|
||||
, fValue(value) {}
|
||||
|
||||
std::string description() const override {
|
||||
return fValue ? "true" : "false";
|
||||
SkString description() const override {
|
||||
return SkString(fValue ? "true" : "false");
|
||||
}
|
||||
|
||||
bool isConstant() const override {
|
||||
|
@ -20,8 +20,8 @@ struct BreakStatement : public Statement {
|
||||
BreakStatement(Position position)
|
||||
: INHERITED(position, kBreak_Kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "break;";
|
||||
SkString description() const override {
|
||||
return SkString("break;");
|
||||
}
|
||||
|
||||
typedef Statement INHERITED;
|
||||
|
@ -21,9 +21,9 @@ struct Constructor : public Expression {
|
||||
: INHERITED(position, kConstructor_Kind, type)
|
||||
, fArguments(std::move(arguments)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fType.description() + "(";
|
||||
std::string separator = "";
|
||||
SkString description() const override {
|
||||
SkString result = fType.description() + "(";
|
||||
SkString separator;
|
||||
for (size_t i = 0; i < fArguments.size(); i++) {
|
||||
result += separator;
|
||||
result += fArguments[i]->description();
|
||||
|
@ -20,8 +20,8 @@ struct ContinueStatement : public Statement {
|
||||
ContinueStatement(Position position)
|
||||
: INHERITED(position, kContinue_Kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "continue;";
|
||||
SkString description() const override {
|
||||
return SkString("continue;");
|
||||
}
|
||||
|
||||
typedef Statement INHERITED;
|
||||
|
@ -20,8 +20,8 @@ struct DiscardStatement : public Statement {
|
||||
DiscardStatement(Position position)
|
||||
: INHERITED(position, kDiscard_Kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "discard;";
|
||||
SkString description() const override {
|
||||
return SkString("discard;");
|
||||
}
|
||||
|
||||
typedef Statement INHERITED;
|
||||
|
@ -23,7 +23,7 @@ struct DoStatement : public Statement {
|
||||
, fStatement(std::move(statement))
|
||||
, fTest(std::move(test)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return "do " + fStatement->description() + " while (" + fTest->description() + ");";
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ struct ExpressionStatement : public Statement {
|
||||
: INHERITED(expression->fPosition, kExpression_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return fExpression->description() + ";";
|
||||
}
|
||||
|
||||
|
@ -16,15 +16,15 @@ namespace SkSL {
|
||||
* An extension declaration.
|
||||
*/
|
||||
struct Extension : public ProgramElement {
|
||||
Extension(Position position, std::string name)
|
||||
Extension(Position position, SkString name)
|
||||
: INHERITED(position, kExtension_Kind)
|
||||
, fName(std::move(name)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return "#extension " + fName + " : enable";
|
||||
}
|
||||
|
||||
const std::string fName;
|
||||
const SkString fName;
|
||||
|
||||
typedef ProgramElement INHERITED;
|
||||
};
|
||||
|
@ -26,7 +26,7 @@ struct Field : public Symbol {
|
||||
, fOwner(owner)
|
||||
, fFieldIndex(fieldIndex) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
virtual SkString description() const override {
|
||||
return fOwner.description() + "." + fOwner.fType.fields()[fFieldIndex].fName;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ struct FieldAccess : public Expression {
|
||||
, fFieldIndex(fieldIndex)
|
||||
, fOwnerKind(ownerKind) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
virtual SkString description() const override {
|
||||
return fBase->description() + "." + fBase->fType.fields()[fFieldIndex].fName;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ struct FloatLiteral : public Expression {
|
||||
: INHERITED(position, kFloatLiteral_Kind, *context.fFloat_Type)
|
||||
, fValue(value) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
virtual SkString description() const override {
|
||||
return to_string(fValue);
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,8 @@ struct ForStatement : public Statement {
|
||||
, fStatement(std::move(statement))
|
||||
, fSymbols(symbols) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = "for (";
|
||||
SkString description() const override {
|
||||
SkString result("for (");
|
||||
if (fInitializer) {
|
||||
result += fInitializer->description();
|
||||
}
|
||||
|
@ -23,9 +23,9 @@ struct FunctionCall : public Expression {
|
||||
, fFunction(std::move(function))
|
||||
, fArguments(std::move(arguments)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fFunction.fName + "(";
|
||||
std::string separator = "";
|
||||
SkString description() const override {
|
||||
SkString result = fFunction.fName + "(";
|
||||
SkString separator;
|
||||
for (size_t i = 0; i < fArguments.size(); i++) {
|
||||
result += separator;
|
||||
result += fArguments[i]->description();
|
||||
|
@ -21,7 +21,7 @@ namespace SkSL {
|
||||
* A function declaration (not a definition -- does not contain a body).
|
||||
*/
|
||||
struct FunctionDeclaration : public Symbol {
|
||||
FunctionDeclaration(Position position, std::string name,
|
||||
FunctionDeclaration(Position position, SkString name,
|
||||
std::vector<const Variable*> parameters, const Type& returnType)
|
||||
: INHERITED(position, kFunctionDeclaration_Kind, std::move(name))
|
||||
, fDefined(false)
|
||||
@ -29,9 +29,9 @@ struct FunctionDeclaration : public Symbol {
|
||||
, fParameters(std::move(parameters))
|
||||
, fReturnType(returnType) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fReturnType.description() + " " + fName + "(";
|
||||
std::string separator = "";
|
||||
SkString description() const override {
|
||||
SkString result = fReturnType.description() + " " + fName + "(";
|
||||
SkString separator;
|
||||
for (auto p : fParameters) {
|
||||
result += separator;
|
||||
separator = ", ";
|
||||
|
@ -24,7 +24,7 @@ struct FunctionDefinition : public ProgramElement {
|
||||
, fDeclaration(declaration)
|
||||
, fBody(std::move(body)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return fDeclaration.description() + " " + fBody->description();
|
||||
}
|
||||
|
||||
|
@ -23,9 +23,9 @@ struct FunctionReference : public Expression {
|
||||
: INHERITED(position, kFunctionReference_Kind, *context.fInvalid_Type)
|
||||
, fFunctions(function) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
virtual SkString description() const override {
|
||||
ASSERT(false);
|
||||
return "<function>";
|
||||
return SkString("<function>");
|
||||
}
|
||||
|
||||
const std::vector<const FunctionDeclaration*> fFunctions;
|
||||
|
@ -22,7 +22,7 @@ struct IRNode {
|
||||
|
||||
virtual ~IRNode() {}
|
||||
|
||||
virtual std::string description() const = 0;
|
||||
virtual SkString description() const = 0;
|
||||
|
||||
const Position fPosition;
|
||||
};
|
||||
|
@ -24,8 +24,8 @@ struct IfStatement : public Statement {
|
||||
, fIfTrue(std::move(ifTrue))
|
||||
, fIfFalse(std::move(ifFalse)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = "if (" + fTest->description() + ") " + fIfTrue->description();
|
||||
SkString description() const override {
|
||||
SkString result = "if (" + fTest->description() + ") " + fIfTrue->description();
|
||||
if (fIfFalse) {
|
||||
result += " else " + fIfFalse->description();
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ struct IndexExpression : public Expression {
|
||||
ASSERT(fIndex->fType == *context.fInt_Type || fIndex->fType == *context.fUInt_Type);
|
||||
}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return fBase->description() + "[" + fIndex->description() + "]";
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ struct IntLiteral : public Expression {
|
||||
: INHERITED(position, kIntLiteral_Kind, type ? *type : *context.fInt_Type)
|
||||
, fValue(value) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
virtual SkString description() const override {
|
||||
return to_string(fValue);
|
||||
}
|
||||
|
||||
|
@ -31,8 +31,8 @@ struct InterfaceBlock : public ProgramElement {
|
||||
ASSERT(fVariable.fType.kind() == Type::kStruct_Kind);
|
||||
}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fVariable.fModifiers.description() + fVariable.fName + " {\n";
|
||||
SkString description() const override {
|
||||
SkString result = fVariable.fModifiers.description() + fVariable.fName + " {\n";
|
||||
for (size_t i = 0; i < fVariable.fType.fields().size(); i++) {
|
||||
result += fVariable.fType.fields()[i].description() + "\n";
|
||||
}
|
||||
|
@ -50,9 +50,9 @@ struct Layout {
|
||||
, fBlendSupportAllEquations(false)
|
||||
, fFormat(ASTLayout::Format::kUnspecified) {}
|
||||
|
||||
std::string description() const {
|
||||
std::string result;
|
||||
std::string separator;
|
||||
SkString description() const {
|
||||
SkString result;
|
||||
SkString separator;
|
||||
if (fLocation >= 0) {
|
||||
result += separator + "location = " + to_string(fLocation);
|
||||
separator = ", ";
|
||||
@ -89,7 +89,7 @@ struct Layout {
|
||||
result += separator + ASTLayout::FormatToStr(fFormat);
|
||||
separator = ", ";
|
||||
}
|
||||
if (result.length() > 0) {
|
||||
if (result.size() > 0) {
|
||||
result = "layout (" + result + ")";
|
||||
}
|
||||
return result;
|
||||
|
@ -38,8 +38,8 @@ struct Modifiers {
|
||||
: fLayout(layout)
|
||||
, fFlags(flags) {}
|
||||
|
||||
std::string description() const {
|
||||
std::string result = fLayout.description();
|
||||
SkString description() const {
|
||||
SkString result = fLayout.description();
|
||||
if (fFlags & kUniform_Flag) {
|
||||
result += "uniform ";
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ struct ModifiersDeclaration : public ProgramElement {
|
||||
: INHERITED(Position(), kModifiers_Kind)
|
||||
, fModifiers(modifiers) {}
|
||||
|
||||
std::string description() const {
|
||||
SkString description() const {
|
||||
return fModifiers.description() + ";";
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ struct PostfixExpression : public Expression {
|
||||
, fOperand(std::move(operand))
|
||||
, fOperator(op) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
virtual SkString description() const override {
|
||||
return fOperand->description() + Token::OperatorName(fOperator);
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ struct PrefixExpression : public Expression {
|
||||
, fOperand(std::move(operand))
|
||||
, fOperator(op) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
virtual SkString description() const override {
|
||||
return Token::OperatorName(fOperator) + fOperand->description();
|
||||
}
|
||||
|
||||
|
@ -24,11 +24,11 @@ struct ReturnStatement : public Statement {
|
||||
: INHERITED(expression->fPosition, kReturn_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
if (fExpression) {
|
||||
return "return " + fExpression->description() + ";";
|
||||
} else {
|
||||
return "return;";
|
||||
return SkString("return;");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,8 +68,8 @@ struct Swizzle : public Expression {
|
||||
ASSERT(fComponents.size() >= 1 && fComponents.size() <= 4);
|
||||
}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fBase->description() + ".";
|
||||
SkString description() const override {
|
||||
SkString result = fBase->description() + ".";
|
||||
for (int x : fComponents) {
|
||||
result += "xyzw"[x];
|
||||
}
|
||||
|
@ -24,13 +24,13 @@ struct Symbol : public IRNode {
|
||||
kField_Kind
|
||||
};
|
||||
|
||||
Symbol(Position position, Kind kind, std::string name)
|
||||
Symbol(Position position, Kind kind, SkString name)
|
||||
: INHERITED(position)
|
||||
, fKind(kind)
|
||||
, fName(std::move(name)) {}
|
||||
|
||||
const Kind fKind;
|
||||
const std::string fName;
|
||||
const SkString fName;
|
||||
|
||||
typedef IRNode INHERITED;
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ std::vector<const FunctionDeclaration*> SymbolTable::GetFunctions(const Symbol&
|
||||
}
|
||||
}
|
||||
|
||||
const Symbol* SymbolTable::operator[](const std::string& name) {
|
||||
const Symbol* SymbolTable::operator[](const SkString& name) {
|
||||
const auto& entry = fSymbols.find(name);
|
||||
if (entry == fSymbols.end()) {
|
||||
if (fParent) {
|
||||
@ -64,12 +64,12 @@ Symbol* SymbolTable::takeOwnership(Symbol* s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
void SymbolTable::add(const std::string& name, std::unique_ptr<Symbol> symbol) {
|
||||
void SymbolTable::add(const SkString& name, std::unique_ptr<Symbol> symbol) {
|
||||
this->addWithoutOwnership(name, symbol.get());
|
||||
fOwnedPointers.push_back(std::move(symbol));
|
||||
}
|
||||
|
||||
void SymbolTable::addWithoutOwnership(const std::string& name, const Symbol* symbol) {
|
||||
void SymbolTable::addWithoutOwnership(const SkString& name, const Symbol* symbol) {
|
||||
const auto& existing = fSymbols.find(name);
|
||||
if (existing == fSymbols.end()) {
|
||||
fSymbols[name] = symbol;
|
||||
|
@ -31,11 +31,11 @@ public:
|
||||
: fParent(parent)
|
||||
, fErrorReporter(errorReporter) {}
|
||||
|
||||
const Symbol* operator[](const std::string& name);
|
||||
const Symbol* operator[](const SkString& name);
|
||||
|
||||
void add(const std::string& name, std::unique_ptr<Symbol> symbol);
|
||||
void add(const SkString& name, std::unique_ptr<Symbol> symbol);
|
||||
|
||||
void addWithoutOwnership(const std::string& name, const Symbol* symbol);
|
||||
void addWithoutOwnership(const SkString& name, const Symbol* symbol);
|
||||
|
||||
Symbol* takeOwnership(Symbol* s);
|
||||
|
||||
@ -48,7 +48,7 @@ private:
|
||||
|
||||
std::vector<std::unique_ptr<Symbol>> fOwnedPointers;
|
||||
|
||||
std::unordered_map<std::string, const Symbol*> fSymbols;
|
||||
std::unordered_map<SkString, const Symbol*> fSymbols;
|
||||
|
||||
ErrorReporter& fErrorReporter;
|
||||
};
|
||||
|
@ -26,7 +26,7 @@ struct TernaryExpression : public Expression {
|
||||
ASSERT(fIfTrue->fType == fIfFalse->fType);
|
||||
}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return "(" + fTest->description() + " ? " + fIfTrue->description() + " : " +
|
||||
fIfFalse->description() + ")";
|
||||
}
|
||||
|
@ -26,17 +26,17 @@ class Context;
|
||||
class Type : public Symbol {
|
||||
public:
|
||||
struct Field {
|
||||
Field(Modifiers modifiers, std::string name, const Type* type)
|
||||
Field(Modifiers modifiers, SkString name, const Type* type)
|
||||
: fModifiers(modifiers)
|
||||
, fName(std::move(name))
|
||||
, fType(std::move(type)) {}
|
||||
|
||||
const std::string description() const {
|
||||
const SkString description() const {
|
||||
return fType->description() + " " + fName + ";";
|
||||
}
|
||||
|
||||
Modifiers fModifiers;
|
||||
std::string fName;
|
||||
SkString fName;
|
||||
const Type* fType;
|
||||
};
|
||||
|
||||
@ -53,14 +53,14 @@ public:
|
||||
|
||||
// Create an "other" (special) type with the given name. These types cannot be directly
|
||||
// referenced from user code.
|
||||
Type(std::string name)
|
||||
Type(SkString name)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kOther_Kind) {}
|
||||
|
||||
// Create a generic type which maps to the listed types. As currently implemented, there are
|
||||
// always exactly four coercion targets, mapping to the scalar, vec2, vec3, and vec4 versions of
|
||||
// a type.
|
||||
Type(std::string name, std::vector<const Type*> types)
|
||||
Type(SkString name, std::vector<const Type*> types)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kGeneric_Kind)
|
||||
, fCoercibleTypes(std::move(types)) {
|
||||
@ -68,13 +68,13 @@ public:
|
||||
}
|
||||
|
||||
// Create a struct type with the given fields.
|
||||
Type(std::string name, std::vector<Field> fields)
|
||||
Type(SkString name, std::vector<Field> fields)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kStruct_Kind)
|
||||
, fFields(std::move(fields)) {}
|
||||
|
||||
// Create a scalar type.
|
||||
Type(std::string name, bool isNumber)
|
||||
Type(SkString name, bool isNumber)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kScalar_Kind)
|
||||
, fIsNumber(isNumber)
|
||||
@ -82,7 +82,7 @@ public:
|
||||
, fRows(1) {}
|
||||
|
||||
// Create a scalar type which can be coerced to the listed types.
|
||||
Type(std::string name, bool isNumber, std::vector<const Type*> coercibleTypes)
|
||||
Type(SkString name, bool isNumber, std::vector<const Type*> coercibleTypes)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kScalar_Kind)
|
||||
, fIsNumber(isNumber)
|
||||
@ -91,11 +91,11 @@ public:
|
||||
, fRows(1) {}
|
||||
|
||||
// Create a vector type.
|
||||
Type(std::string name, const Type& componentType, int columns)
|
||||
Type(SkString name, const Type& componentType, int columns)
|
||||
: Type(name, kVector_Kind, componentType, columns) {}
|
||||
|
||||
// Create a vector or array type.
|
||||
Type(std::string name, Kind kind, const Type& componentType, int columns)
|
||||
Type(SkString name, Kind kind, const Type& componentType, int columns)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kind)
|
||||
, fComponentType(&componentType)
|
||||
@ -104,7 +104,7 @@ public:
|
||||
, fDimensions(SpvDim1D) {}
|
||||
|
||||
// Create a matrix type.
|
||||
Type(std::string name, const Type& componentType, int columns, int rows)
|
||||
Type(SkString name, const Type& componentType, int columns, int rows)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kMatrix_Kind)
|
||||
, fComponentType(&componentType)
|
||||
@ -113,7 +113,7 @@ public:
|
||||
, fDimensions(SpvDim1D) {}
|
||||
|
||||
// Create a sampler type.
|
||||
Type(std::string name, SpvDim_ dimensions, bool isDepth, bool isArrayed, bool isMultisampled,
|
||||
Type(SkString name, SpvDim_ dimensions, bool isDepth, bool isArrayed, bool isMultisampled,
|
||||
bool isSampled)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kSampler_Kind)
|
||||
@ -123,11 +123,11 @@ public:
|
||||
, fIsMultisampled(isMultisampled)
|
||||
, fIsSampled(isSampled) {}
|
||||
|
||||
std::string name() const {
|
||||
SkString name() const {
|
||||
return fName;
|
||||
}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return fName;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ struct TypeReference : public Expression {
|
||||
: INHERITED(position, kTypeReference_Kind, *context.fInvalid_Type)
|
||||
, fValue(type) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return fValue.name();
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ struct UnresolvedFunction : public Symbol {
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual std::string description() const override {
|
||||
virtual SkString description() const override {
|
||||
return fName;
|
||||
}
|
||||
|
||||
|
@ -27,8 +27,8 @@ struct VarDeclaration {
|
||||
, fSizes(std::move(sizes))
|
||||
, fValue(std::move(value)) {}
|
||||
|
||||
std::string description() const {
|
||||
std::string result = fVar->fName;
|
||||
SkString description() const {
|
||||
SkString result = fVar->fName;
|
||||
for (const auto& size : fSizes) {
|
||||
if (size) {
|
||||
result += "[" + size->description() + "]";
|
||||
@ -57,13 +57,12 @@ struct VarDeclarations : public ProgramElement {
|
||||
, fBaseType(*baseType)
|
||||
, fVars(std::move(vars)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
if (!fVars.size()) {
|
||||
return "";
|
||||
return SkString();
|
||||
}
|
||||
std::string result = fVars[0].fVar->fModifiers.description() + fBaseType.description() +
|
||||
" ";
|
||||
std::string separator = "";
|
||||
SkString result = fVars[0].fVar->fModifiers.description() + fBaseType.description() + " ";
|
||||
SkString separator;
|
||||
for (const auto& var : fVars) {
|
||||
result += separator;
|
||||
separator = ", ";
|
||||
|
@ -21,7 +21,7 @@ struct VarDeclarationsStatement : public Statement {
|
||||
: INHERITED(decl->fPosition, kVarDeclarations_Kind)
|
||||
, fDeclaration(std::move(decl)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return fDeclaration->description();
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ struct Variable : public Symbol {
|
||||
kParameter_Storage
|
||||
};
|
||||
|
||||
Variable(Position position, Modifiers modifiers, std::string name, const Type& type,
|
||||
Variable(Position position, Modifiers modifiers, SkString name, const Type& type,
|
||||
Storage storage)
|
||||
: INHERITED(position, kVariable_Kind, std::move(name))
|
||||
, fModifiers(modifiers)
|
||||
@ -36,7 +36,7 @@ struct Variable : public Symbol {
|
||||
, fIsReadFrom(false)
|
||||
, fIsWrittenTo(false) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
virtual SkString description() const override {
|
||||
return fModifiers.description() + fType.fName + " " + fName;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ struct VariableReference : public Expression {
|
||||
: INHERITED(position, kVariableReference_Kind, variable.fType)
|
||||
, fVariable(variable) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return fVariable.fName;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ struct WhileStatement : public Statement {
|
||||
, fTest(std::move(test))
|
||||
, fStatement(std::move(statement)) {}
|
||||
|
||||
std::string description() const override {
|
||||
SkString description() const override {
|
||||
return "while (" + fTest->description() + ") " + fStatement->description();
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user