When converting runtime SkSL to FP SkSL, use default settings
Anything related to caps should be resolved in the second compile. However, when calling toPipelineStage, the settings stored in the base Program are used, so we need to inject them at that point. This also removes the cache of specialized programs. We only hit that code path when we're about to do a full compile, including generating SkSL, turning that into GLSL, etc. The specialization is implicitly cached as part of the entire program for common cases, so the second level isn't that useful. Change-Id: I53bc54b0611951e1d97278d59881308c6b152090 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/259162 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
acf5929ae0
commit
48fcf36e15
@ -73,7 +73,7 @@ protected:
|
||||
SkASSERT(caps && !FPFactoryCache);
|
||||
SkASSERT(!fThreadSafeProxy);
|
||||
|
||||
FPFactoryCache.reset(new GrSkSLFPFactoryCache(caps->refShaderCaps()));
|
||||
FPFactoryCache.reset(new GrSkSLFPFactoryCache());
|
||||
fThreadSafeProxy = GrContextThreadSafeProxyPriv::Make(this->backend(),
|
||||
this->options(),
|
||||
this->contextID(),
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <vector>
|
||||
#include "include/core/SkRefCnt.h"
|
||||
|
||||
class GrShaderCaps;
|
||||
class GrSkSLFPFactory;
|
||||
|
||||
// This is a cache used by GrSkSLFP to retain GrSkSLFPFactory instances, so we don't have to
|
||||
@ -21,7 +20,6 @@ class GrSkSLFPFactory;
|
||||
// onGetGLSLProcessorKey.
|
||||
class GrSkSLFPFactoryCache : public SkNVRefCnt<GrSkSLFPFactoryCache> {
|
||||
public:
|
||||
GrSkSLFPFactoryCache(sk_sp<const GrShaderCaps> shaderCaps) : fShaderCaps(shaderCaps) {}
|
||||
~GrSkSLFPFactoryCache();
|
||||
|
||||
sk_sp<GrSkSLFPFactory> findOrCreate(int index, const char* name, const char* skSL);
|
||||
@ -37,7 +35,6 @@ private:
|
||||
mutable SkMutex fCacheMutex;
|
||||
|
||||
std::vector<sk_sp<GrSkSLFPFactory>> fFactories;
|
||||
sk_sp<const GrShaderCaps> fShaderCaps;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -18,10 +18,9 @@
|
||||
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
|
||||
|
||||
GrSkSLFPFactory::GrSkSLFPFactory(const char* name, const GrShaderCaps* shaderCaps, const char* sksl)
|
||||
GrSkSLFPFactory::GrSkSLFPFactory(const char* name, const char* sksl)
|
||||
: fName(name) {
|
||||
SkSL::Program::Settings settings;
|
||||
settings.fCaps = shaderCaps;
|
||||
fBaseProgram = fCompiler.convertProgram(SkSL::Program::kPipelineStage_Kind,
|
||||
SkSL::String(sksl), settings);
|
||||
if (fCompiler.errorCount()) {
|
||||
@ -58,13 +57,8 @@ static std::tuple<const SkSL::Type*, int> strip_array(const SkSL::Type* type) {
|
||||
return std::make_tuple(type, arrayCount);
|
||||
}
|
||||
|
||||
const SkSL::Program* GrSkSLFPFactory::getSpecialization(const SkSL::String& key, const void* inputs,
|
||||
size_t inputSize) {
|
||||
const auto& found = fSpecializations.find(key);
|
||||
if (found != fSpecializations.end()) {
|
||||
return found->second.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<SkSL::Program> GrSkSLFPFactory::getSpecialization(const void* inputs,
|
||||
size_t inputSize) {
|
||||
std::unordered_map<SkSL::String, SkSL::Program::Settings::Value> inputMap;
|
||||
size_t offset = 0;
|
||||
for (const auto& v : fInAndUniformVars) {
|
||||
@ -116,9 +110,7 @@ const SkSL::Program* GrSkSLFPFactory::getSpecialization(const SkSL::String& key,
|
||||
SkDebugf("%s\n", fCompiler.errorText().c_str());
|
||||
SkASSERT(false);
|
||||
}
|
||||
const SkSL::Program* result = specialized.get();
|
||||
fSpecializations.insert(std::make_pair(key, std::move(specialized)));
|
||||
return result;
|
||||
return specialized;
|
||||
}
|
||||
|
||||
static std::tuple<SkSL::Layout::CType, int> get_ctype(const SkSL::Context& context,
|
||||
@ -380,6 +372,7 @@ std::unique_ptr<GrSkSLFP> GrSkSLFP::Make(GrContext_Base* context, int index, con
|
||||
const char* sksl, const void* inputs, size_t inputSize,
|
||||
const SkMatrix* matrix) {
|
||||
return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->priv().fpFactoryCache(),
|
||||
context->priv().caps()->refShaderCaps(),
|
||||
index, name, sksl, SkString(),
|
||||
inputs, inputSize, matrix));
|
||||
}
|
||||
@ -388,16 +381,18 @@ std::unique_ptr<GrSkSLFP> GrSkSLFP::Make(GrContext_Base* context, int index, con
|
||||
SkString sksl, const void* inputs, size_t inputSize,
|
||||
const SkMatrix* matrix) {
|
||||
return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->priv().fpFactoryCache(),
|
||||
context->priv().caps()->refShaderCaps(),
|
||||
index, name, nullptr, std::move(sksl),
|
||||
inputs, inputSize, matrix));
|
||||
}
|
||||
|
||||
GrSkSLFP::GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache,
|
||||
GrSkSLFP::GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, sk_sp<const GrShaderCaps> shaderCaps,
|
||||
int index, const char* name, const char* sksl,
|
||||
SkString skslString, const void* inputs, size_t inputSize,
|
||||
const SkMatrix* matrix)
|
||||
: INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
|
||||
, fFactoryCache(factoryCache)
|
||||
, fShaderCaps(std::move(shaderCaps))
|
||||
, fIndex(index)
|
||||
, fName(name)
|
||||
, fSkSLString(skslString)
|
||||
@ -416,6 +411,7 @@ GrSkSLFP::GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache,
|
||||
GrSkSLFP::GrSkSLFP(const GrSkSLFP& other)
|
||||
: INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
|
||||
, fFactoryCache(other.fFactoryCache)
|
||||
, fShaderCaps(other.fShaderCaps)
|
||||
, fFactory(other.fFactory)
|
||||
, fIndex(other.fIndex)
|
||||
, fName(other.fName)
|
||||
@ -448,7 +444,9 @@ void GrSkSLFP::addChild(std::unique_ptr<GrFragmentProcessor> child) {
|
||||
|
||||
GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
|
||||
this->createFactory();
|
||||
const SkSL::Program* specialized = fFactory->getSpecialization(fKey, fInputs.get(), fInputSize);
|
||||
auto specialized = fFactory->getSpecialization(fInputs.get(), fInputSize);
|
||||
specialized->fSettings.fCaps = fShaderCaps.get();
|
||||
|
||||
SkSL::String glsl;
|
||||
std::vector<SkSL::Compiler::FormatArg> formatArgs;
|
||||
std::vector<SkSL::Compiler::GLSLFunction> functions;
|
||||
@ -460,19 +458,6 @@ 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();
|
||||
@ -489,7 +474,6 @@ void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
|
||||
switch (ctype) {
|
||||
case SkSL::Layout::CType::kBool:
|
||||
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
||||
fKey += inputs[offset];
|
||||
b->add32(inputs[offset]);
|
||||
}
|
||||
++offset;
|
||||
@ -497,10 +481,6 @@ void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
|
||||
case SkSL::Layout::CType::kInt32: {
|
||||
offset = SkAlign4(offset);
|
||||
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
||||
fKey += inputs[offset + 0];
|
||||
fKey += inputs[offset + 1];
|
||||
fKey += inputs[offset + 2];
|
||||
fKey += inputs[offset + 3];
|
||||
b->add32(*(int32_t*)(inputs + offset));
|
||||
}
|
||||
offset += sizeof(int32_t);
|
||||
@ -509,28 +489,33 @@ void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
|
||||
case SkSL::Layout::CType::kFloat: {
|
||||
offset = SkAlign4(offset);
|
||||
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
||||
fKey += inputs[offset + 0];
|
||||
fKey += inputs[offset + 1];
|
||||
fKey += inputs[offset + 2];
|
||||
fKey += inputs[offset + 3];
|
||||
b->add32(*(float*)(inputs + offset));
|
||||
}
|
||||
offset += sizeof(float);
|
||||
break;
|
||||
}
|
||||
case SkSL::Layout::CType::kFloat2:
|
||||
copy_floats_key(inputs, b, v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag, 2,
|
||||
&offset, &fKey);
|
||||
offset = SkAlign4(offset);
|
||||
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
||||
memcpy(b->add32n(2), inputs + offset, 2 * sizeof(float));
|
||||
}
|
||||
offset += 2 * sizeof(float);
|
||||
break;
|
||||
case SkSL::Layout::CType::kFloat3:
|
||||
copy_floats_key(inputs, b, v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag, 3,
|
||||
&offset, &fKey);
|
||||
offset = SkAlign4(offset);
|
||||
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
||||
memcpy(b->add32n(3), inputs + offset, 3 * sizeof(float));
|
||||
}
|
||||
offset += 3 * sizeof(float);
|
||||
break;
|
||||
case SkSL::Layout::CType::kSkPMColor:
|
||||
case SkSL::Layout::CType::kSkPMColor4f:
|
||||
case SkSL::Layout::CType::kSkRect:
|
||||
copy_floats_key(inputs, b, v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag, 4,
|
||||
&offset, &fKey);
|
||||
offset = SkAlign4(offset);
|
||||
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
||||
memcpy(b->add32n(4), inputs + offset, 4 * sizeof(float));
|
||||
}
|
||||
offset += 4 * sizeof(float);
|
||||
break;
|
||||
default:
|
||||
// unsupported input var type
|
||||
@ -566,7 +551,7 @@ sk_sp<GrSkSLFPFactory> GrSkSLFPFactoryCache::findOrCreate(int index, const char*
|
||||
|
||||
sk_sp<GrSkSLFPFactory> factory = this->get(index);
|
||||
if (!factory) {
|
||||
factory = sk_sp<GrSkSLFPFactory>(new GrSkSLFPFactory(name, fShaderCaps.get(), skSL));
|
||||
factory = sk_sp<GrSkSLFPFactory>(new GrSkSLFPFactory(name, skSL));
|
||||
this->set(index, factory);
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ public:
|
||||
std::unique_ptr<GrFragmentProcessor> clone() const override;
|
||||
|
||||
private:
|
||||
GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache,
|
||||
GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, sk_sp<const GrShaderCaps> shaderCaps,
|
||||
int fIndex, const char* name, const char* sksl,
|
||||
SkString skslString, const void* inputs, size_t inputSize, const SkMatrix* matrix);
|
||||
|
||||
@ -125,6 +125,7 @@ private:
|
||||
void createFactory() const;
|
||||
|
||||
sk_sp<GrSkSLFPFactoryCache> fFactoryCache;
|
||||
sk_sp<const GrShaderCaps> fShaderCaps;
|
||||
|
||||
mutable sk_sp<GrSkSLFPFactory> fFactory;
|
||||
|
||||
@ -148,8 +149,6 @@ private:
|
||||
|
||||
GrCoordTransform fCoordTransform;
|
||||
|
||||
mutable SkSL::String fKey;
|
||||
|
||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
|
||||
|
||||
typedef GrFragmentProcessor INHERITED;
|
||||
@ -172,10 +171,9 @@ public:
|
||||
* the produced shaders to differ), so it is important to reuse the same factory instance for
|
||||
* the same shader in order to avoid repeatedly re-parsing the SkSL.
|
||||
*/
|
||||
GrSkSLFPFactory(const char* name, const GrShaderCaps* shaderCaps, const char* sksl);
|
||||
GrSkSLFPFactory(const char* name, const char* sksl);
|
||||
|
||||
const SkSL::Program* getSpecialization(const SkSL::String& key, const void* inputs,
|
||||
size_t inputSize);
|
||||
std::unique_ptr<SkSL::Program> getSpecialization(const void* inputs, size_t inputSize);
|
||||
|
||||
const char* fName;
|
||||
|
||||
@ -185,8 +183,6 @@ public:
|
||||
|
||||
std::vector<const SkSL::Variable*> fInAndUniformVars;
|
||||
|
||||
std::unordered_map<SkSL::String, std::unique_ptr<const SkSL::Program>> fSpecializations;
|
||||
|
||||
friend class GrSkSLFP;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user