Reland "Fixed some GrSkSLFP limitations."

This is a reland of 190157bff2

Original change's description:
> Fixed some GrSkSLFP limitations.
> 
> This makes it possible to pass more types as uniforms / inputs and fixes an
> issue with non-main functions calling other non-main functions.
> 
> Change-Id: I6b5623b3c967d8219b992a455cc68bb0a29706b8
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/255300
> Reviewed-by: Brian Osman <brianosman@google.com>
> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>

Change-Id: Icc06cd54abb7acc83415915e16ca64c3eb6b943b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/255779
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
Ethan Nicholas 2019-11-21 11:14:11 -05:00 committed by Skia Commit-Bot
parent 119ac6d1b7
commit fc671ad888
4 changed files with 151 additions and 72 deletions

View File

@ -76,6 +76,12 @@ const SkSL::Program* GrSkSLFPFactory::getSpecialization(const SkSL::String& key,
bool v = *(((bool*) inputs) + offset);
inputMap.insert(std::make_pair(name, SkSL::Program::Settings::Value(v)));
offset += sizeof(bool);
} else if (&v->fType == fCompiler.context().fFloat2_Type.get() ||
&v->fType == fCompiler.context().fHalf2_Type.get()) {
offset = SkAlign4(offset) + sizeof(float) * 2;
} else if (&v->fType == fCompiler.context().fFloat3_Type.get() ||
&v->fType == fCompiler.context().fHalf3_Type.get()) {
offset = SkAlign4(offset) + sizeof(float) * 3;
} else if (&v->fType == fCompiler.context().fFloat4_Type.get() ||
&v->fType == fCompiler.context().fHalf4_Type.get()) {
offset = SkAlign4(offset) + sizeof(float) * 4;
@ -103,6 +109,10 @@ static SkSL::Layout::CType get_ctype(const SkSL::Context& context, const SkSL::V
if (result == SkSL::Layout::CType::kDefault) {
if (&v.fType == context.fFloat_Type.get()) {
result = SkSL::Layout::CType::kFloat;
} else if (&v.fType == context.fFloat2_Type.get()) {
result = SkSL::Layout::CType::kFloat2;
} else if (&v.fType == context.fFloat3_Type.get()) {
result = SkSL::Layout::CType::kFloat3;
} else if (&v.fType == context.fFloat4_Type.get()) {
result = SkSL::Layout::CType::kSkRect;
} else if (&v.fType == context.fHalf4_Type.get()) {
@ -139,10 +149,22 @@ public:
return kFloat2_GrSLType;
} else if (type == *fContext.fHalf2_Type) {
return kHalf2_GrSLType;
} else if (type == *fContext.fFloat3_Type) {
return kFloat3_GrSLType;
} else if (type == *fContext.fHalf3_Type) {
return kHalf3_GrSLType;
} else if (type == *fContext.fFloat4_Type) {
return kFloat4_GrSLType;
} else if (type == *fContext.fHalf4_Type) {
return kHalf4_GrSLType;
} else if (type == *fContext.fFloat2x2_Type) {
return kFloat2x2_GrSLType;
} else if (type == *fContext.fHalf2x2_Type) {
return kHalf2x2_GrSLType;
} else if (type == *fContext.fFloat3x3_Type) {
return kFloat3x3_GrSLType;
} else if (type == *fContext.fHalf3x3_Type) {
return kHalf3x3_GrSLType;
} else if (type == *fContext.fFloat4x4_Type) {
return kFloat4x4_GrSLType;
} else if (type == *fContext.fHalf4x4_Type) {
@ -156,6 +178,64 @@ public:
SK_ABORT("unsupported uniform type");
}
SkSL::String expandFormatArgs(const SkSL::String& raw,
const EmitArgs& args,
const std::vector<SkSL::Compiler::FormatArg> formatArgs,
const char* coordsName,
const std::vector<SkString>& childNames) {
SkSL::String result;
int substringStartIndex = 0;
int formatArgIndex = 0;
for (size_t i = 0; i < raw.length(); ++i) {
char c = raw[i];
if (c == '%') {
result += SkSL::StringFragment(raw.c_str() + substringStartIndex,
i - substringStartIndex);
++i;
c = raw[i];
switch (c) {
case 's': {
const SkSL::Compiler::FormatArg& arg = formatArgs[formatArgIndex++];
switch (arg.fKind) {
case SkSL::Compiler::FormatArg::Kind::kInput:
result += args.fInputColor;
break;
case SkSL::Compiler::FormatArg::Kind::kOutput:
result += args.fOutputColor;
break;
case SkSL::Compiler::FormatArg::Kind::kCoordX:
result += coordsName;
result += ".x";
break;
case SkSL::Compiler::FormatArg::Kind::kCoordY:
result += coordsName;
result += ".y";
break;
case SkSL::Compiler::FormatArg::Kind::kUniform:
result += args.fUniformHandler->getUniformCStr(
fUniformHandles[arg.fIndex]);
break;
case SkSL::Compiler::FormatArg::Kind::kChildProcessor:
result += childNames[arg.fIndex].c_str();
break;
case SkSL::Compiler::FormatArg::Kind::kFunctionName:
SkASSERT((int) fFunctionNames.size() > arg.fIndex);
result += fFunctionNames[arg.fIndex].c_str();
break;
}
break;
}
default:
result += c;
}
substringStartIndex = i + 1;
}
}
result += SkSL::StringFragment(raw.c_str() + substringStartIndex,
raw.length() - substringStartIndex);
return result;
}
void emitCode(EmitArgs& args) override {
for (const auto& v : fInAndUniformVars) {
if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag && v->fType !=
@ -167,69 +247,27 @@ public:
}
}
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
for (const auto& f : fFunctions) {
fFunctionNames.emplace_back();
fragBuilder->emitFunction(f.fReturnType,
f.fName.c_str(),
f.fParameters.size(),
f.fParameters.data(),
f.fBody.c_str(),
&fFunctionNames.back());
}
SkString coords = args.fTransformedCoords.count()
? fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint)
: SkString("sk_FragCoord");
std::vector<SkString> childNames;
for (int i = 0; i < this->numChildProcessors(); ++i) {
childNames.push_back(SkStringPrintf("_child%d", i));
this->invokeChild(i, &childNames[i], args);
}
int substringStartIndex = 0;
int formatArgIndex = 0;
SkString coords = args.fTransformedCoords.count()
? fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint)
: SkString("sk_FragCoord");
for (size_t i = 0; i < fGLSL.length(); ++i) {
char c = fGLSL[i];
if (c == '%') {
fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
i - substringStartIndex);
++i;
c = fGLSL[i];
switch (c) {
case 's': {
SkSL::Compiler::FormatArg& arg = fFormatArgs[formatArgIndex++];
switch (arg.fKind) {
case SkSL::Compiler::FormatArg::Kind::kInput:
fragBuilder->codeAppend(args.fInputColor);
break;
case SkSL::Compiler::FormatArg::Kind::kOutput:
fragBuilder->codeAppend(args.fOutputColor);
break;
case SkSL::Compiler::FormatArg::Kind::kCoordX:
fragBuilder->codeAppendf("%s.x", coords.c_str());
break;
case SkSL::Compiler::FormatArg::Kind::kCoordY:
fragBuilder->codeAppendf("%s.y", coords.c_str());
break;
case SkSL::Compiler::FormatArg::Kind::kUniform:
fragBuilder->codeAppend(args.fUniformHandler->getUniformCStr(
fUniformHandles[arg.fIndex]));
break;
case SkSL::Compiler::FormatArg::Kind::kChildProcessor:
fragBuilder->codeAppend(childNames[arg.fIndex].c_str());
break;
case SkSL::Compiler::FormatArg::Kind::kFunctionName:
fragBuilder->codeAppend(fFunctionNames[arg.fIndex].c_str());
break;
}
break;
}
default:
fragBuilder->codeAppendf("%c", c);
}
substringStartIndex = i + 1;
}
for (const auto& f : fFunctions) {
fFunctionNames.emplace_back();
SkSL::String body = this->expandFormatArgs(f.fBody.c_str(), args, f.fFormatArgs,
coords.c_str(), childNames);
fragBuilder->emitFunction(f.fReturnType,
f.fName.c_str(),
f.fParameters.size(),
f.fParameters.data(),
body.c_str(),
&fFunctionNames.back());
}
fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
fGLSL.length() - substringStartIndex);
fragBuilder->codeAppend(this->expandFormatArgs(fGLSL.c_str(), args, fFormatArgs,
coords.c_str(), childNames).c_str());
}
void onSetData(const GrGLSLProgramDataManager& pdman,
@ -250,6 +288,30 @@ public:
}
break;
}
case SkSL::Layout::CType::kFloat2: {
offset = SkAlign4(offset);
float f1 = *(float*) (inputs + offset);
offset += sizeof(float);
float f2 = *(float*) (inputs + offset);
offset += sizeof(float);
if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
pdman.set2f(fUniformHandles[uniformIndex++], f1, f2);
}
break;
}
case SkSL::Layout::CType::kFloat3: {
offset = SkAlign4(offset);
float f1 = *(float*) (inputs + offset);
offset += sizeof(float);
float f2 = *(float*) (inputs + offset);
offset += sizeof(float);
float f3 = *(float*) (inputs + offset);
offset += sizeof(float);
if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
pdman.set3f(fUniformHandles[uniformIndex++], f1, f2, f3);
}
break;
}
case SkSL::Layout::CType::kSkPMColor4f:
case SkSL::Layout::CType::kSkRect: {
offset = SkAlign4(offset);
@ -398,6 +460,19 @@ GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
formatArgs, functions);
}
static void copy_floats_key(char* inputs, GrProcessorKeyBuilder* b, bool isIn, int count,
size_t* offset, SkSL::String* key) {
if (isIn) {
for (size_t i = 0; i < sizeof(float) * count; ++i) {
(*key) += inputs[*offset + i];
b->add32(*(int32_t*) (inputs + *offset));
(*offset) += sizeof(float);
}
} else {
(*offset) += sizeof(float) * count;
}
}
void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
GrProcessorKeyBuilder* b) const {
this->createFactory();
@ -441,24 +516,19 @@ void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
offset += sizeof(float);
break;
}
case SkSL::Layout::CType::kFloat2:
copy_floats_key(inputs, b, v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag, 2,
&offset, &fKey);
break;
case SkSL::Layout::CType::kFloat3:
copy_floats_key(inputs, b, v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag, 3,
&offset, &fKey);
break;
case SkSL::Layout::CType::kSkPMColor:
case SkSL::Layout::CType::kSkPMColor4f:
case SkSL::Layout::CType::kSkRect:
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
for (size_t i = 0; i < sizeof(float) * 4; ++i) {
fKey += inputs[offset + i];
}
b->add32(*(int32_t*) (inputs + offset));
offset += sizeof(float);
b->add32(*(int32_t*) (inputs + offset));
offset += sizeof(float);
b->add32(*(int32_t*) (inputs + offset));
offset += sizeof(float);
b->add32(*(int32_t*) (inputs + offset));
offset += sizeof(float);
} else {
offset += sizeof(float) * 4;
}
copy_floats_key(inputs, b, v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag, 4,
&offset, &fKey);
break;
default:
// unsupported input var type

View File

@ -102,6 +102,7 @@ public:
SkString fName;
std::vector<GrShaderVar> fParameters;
SkString fBody;
std::vector<Compiler::FormatArg> fFormatArgs;
};
#endif

View File

@ -215,6 +215,10 @@ static GrSLType glsltype(const Context& context, const Type& type) {
return GrSLType::kFloat2_GrSLType;
} else if (type == *context.fHalf2_Type) {
return GrSLType::kHalf2_GrSLType;
} else if (type == *context.fFloat3_Type) {
return GrSLType::kFloat3_GrSLType;
} else if (type == *context.fHalf3_Type) {
return GrSLType::kHalf3_GrSLType;
} else if (type == *context.fFloat4_Type) {
return GrSLType::kFloat4_GrSLType;
} else if (type == *context.fHalf4_Type) {
@ -262,6 +266,7 @@ void PipelineStageCodeGenerator::writeFunction(const FunctionDefinition& f) {
}
fOut = oldOut;
result.fBody = buffer.str();
result.fFormatArgs = std::move(*fFormatArgs);
fFunctions->push_back(result);
}
}

View File

@ -82,6 +82,9 @@ struct Layout {
kDefault,
kBool,
kFloat,
kFloat2,
kFloat3,
kFloat4,
kInt32,
kSkRect,
kSkIRect,