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(caps && !FPFactoryCache);
|
||||||
SkASSERT(!fThreadSafeProxy);
|
SkASSERT(!fThreadSafeProxy);
|
||||||
|
|
||||||
FPFactoryCache.reset(new GrSkSLFPFactoryCache(caps->refShaderCaps()));
|
FPFactoryCache.reset(new GrSkSLFPFactoryCache());
|
||||||
fThreadSafeProxy = GrContextThreadSafeProxyPriv::Make(this->backend(),
|
fThreadSafeProxy = GrContextThreadSafeProxyPriv::Make(this->backend(),
|
||||||
this->options(),
|
this->options(),
|
||||||
this->contextID(),
|
this->contextID(),
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "include/core/SkRefCnt.h"
|
#include "include/core/SkRefCnt.h"
|
||||||
|
|
||||||
class GrShaderCaps;
|
|
||||||
class GrSkSLFPFactory;
|
class GrSkSLFPFactory;
|
||||||
|
|
||||||
// This is a cache used by GrSkSLFP to retain GrSkSLFPFactory instances, so we don't have to
|
// This is a cache used by GrSkSLFP to retain GrSkSLFPFactory instances, so we don't have to
|
||||||
@ -21,7 +20,6 @@ class GrSkSLFPFactory;
|
|||||||
// onGetGLSLProcessorKey.
|
// onGetGLSLProcessorKey.
|
||||||
class GrSkSLFPFactoryCache : public SkNVRefCnt<GrSkSLFPFactoryCache> {
|
class GrSkSLFPFactoryCache : public SkNVRefCnt<GrSkSLFPFactoryCache> {
|
||||||
public:
|
public:
|
||||||
GrSkSLFPFactoryCache(sk_sp<const GrShaderCaps> shaderCaps) : fShaderCaps(shaderCaps) {}
|
|
||||||
~GrSkSLFPFactoryCache();
|
~GrSkSLFPFactoryCache();
|
||||||
|
|
||||||
sk_sp<GrSkSLFPFactory> findOrCreate(int index, const char* name, const char* skSL);
|
sk_sp<GrSkSLFPFactory> findOrCreate(int index, const char* name, const char* skSL);
|
||||||
@ -37,7 +35,6 @@ private:
|
|||||||
mutable SkMutex fCacheMutex;
|
mutable SkMutex fCacheMutex;
|
||||||
|
|
||||||
std::vector<sk_sp<GrSkSLFPFactory>> fFactories;
|
std::vector<sk_sp<GrSkSLFPFactory>> fFactories;
|
||||||
sk_sp<const GrShaderCaps> fShaderCaps;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,10 +18,9 @@
|
|||||||
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
|
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
|
||||||
#include "src/gpu/glsl/GrGLSLProgramBuilder.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) {
|
: fName(name) {
|
||||||
SkSL::Program::Settings settings;
|
SkSL::Program::Settings settings;
|
||||||
settings.fCaps = shaderCaps;
|
|
||||||
fBaseProgram = fCompiler.convertProgram(SkSL::Program::kPipelineStage_Kind,
|
fBaseProgram = fCompiler.convertProgram(SkSL::Program::kPipelineStage_Kind,
|
||||||
SkSL::String(sksl), settings);
|
SkSL::String(sksl), settings);
|
||||||
if (fCompiler.errorCount()) {
|
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);
|
return std::make_tuple(type, arrayCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SkSL::Program* GrSkSLFPFactory::getSpecialization(const SkSL::String& key, const void* inputs,
|
std::unique_ptr<SkSL::Program> GrSkSLFPFactory::getSpecialization(const void* inputs,
|
||||||
size_t inputSize) {
|
size_t inputSize) {
|
||||||
const auto& found = fSpecializations.find(key);
|
|
||||||
if (found != fSpecializations.end()) {
|
|
||||||
return found->second.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unordered_map<SkSL::String, SkSL::Program::Settings::Value> inputMap;
|
std::unordered_map<SkSL::String, SkSL::Program::Settings::Value> inputMap;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
for (const auto& v : fInAndUniformVars) {
|
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());
|
SkDebugf("%s\n", fCompiler.errorText().c_str());
|
||||||
SkASSERT(false);
|
SkASSERT(false);
|
||||||
}
|
}
|
||||||
const SkSL::Program* result = specialized.get();
|
return specialized;
|
||||||
fSpecializations.insert(std::make_pair(key, std::move(specialized)));
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::tuple<SkSL::Layout::CType, int> get_ctype(const SkSL::Context& context,
|
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 char* sksl, const void* inputs, size_t inputSize,
|
||||||
const SkMatrix* matrix) {
|
const SkMatrix* matrix) {
|
||||||
return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->priv().fpFactoryCache(),
|
return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->priv().fpFactoryCache(),
|
||||||
|
context->priv().caps()->refShaderCaps(),
|
||||||
index, name, sksl, SkString(),
|
index, name, sksl, SkString(),
|
||||||
inputs, inputSize, matrix));
|
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,
|
SkString sksl, const void* inputs, size_t inputSize,
|
||||||
const SkMatrix* matrix) {
|
const SkMatrix* matrix) {
|
||||||
return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->priv().fpFactoryCache(),
|
return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->priv().fpFactoryCache(),
|
||||||
|
context->priv().caps()->refShaderCaps(),
|
||||||
index, name, nullptr, std::move(sksl),
|
index, name, nullptr, std::move(sksl),
|
||||||
inputs, inputSize, matrix));
|
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,
|
int index, const char* name, const char* sksl,
|
||||||
SkString skslString, const void* inputs, size_t inputSize,
|
SkString skslString, const void* inputs, size_t inputSize,
|
||||||
const SkMatrix* matrix)
|
const SkMatrix* matrix)
|
||||||
: INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
|
: INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
|
||||||
, fFactoryCache(factoryCache)
|
, fFactoryCache(factoryCache)
|
||||||
|
, fShaderCaps(std::move(shaderCaps))
|
||||||
, fIndex(index)
|
, fIndex(index)
|
||||||
, fName(name)
|
, fName(name)
|
||||||
, fSkSLString(skslString)
|
, fSkSLString(skslString)
|
||||||
@ -416,6 +411,7 @@ GrSkSLFP::GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache,
|
|||||||
GrSkSLFP::GrSkSLFP(const GrSkSLFP& other)
|
GrSkSLFP::GrSkSLFP(const GrSkSLFP& other)
|
||||||
: INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
|
: INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
|
||||||
, fFactoryCache(other.fFactoryCache)
|
, fFactoryCache(other.fFactoryCache)
|
||||||
|
, fShaderCaps(other.fShaderCaps)
|
||||||
, fFactory(other.fFactory)
|
, fFactory(other.fFactory)
|
||||||
, fIndex(other.fIndex)
|
, fIndex(other.fIndex)
|
||||||
, fName(other.fName)
|
, fName(other.fName)
|
||||||
@ -448,7 +444,9 @@ void GrSkSLFP::addChild(std::unique_ptr<GrFragmentProcessor> child) {
|
|||||||
|
|
||||||
GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
|
GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
|
||||||
this->createFactory();
|
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;
|
SkSL::String glsl;
|
||||||
std::vector<SkSL::Compiler::FormatArg> formatArgs;
|
std::vector<SkSL::Compiler::FormatArg> formatArgs;
|
||||||
std::vector<SkSL::Compiler::GLSLFunction> functions;
|
std::vector<SkSL::Compiler::GLSLFunction> functions;
|
||||||
@ -460,19 +458,6 @@ GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
|
|||||||
formatArgs, functions);
|
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,
|
void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
|
||||||
GrProcessorKeyBuilder* b) const {
|
GrProcessorKeyBuilder* b) const {
|
||||||
this->createFactory();
|
this->createFactory();
|
||||||
@ -489,7 +474,6 @@ void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
|
|||||||
switch (ctype) {
|
switch (ctype) {
|
||||||
case SkSL::Layout::CType::kBool:
|
case SkSL::Layout::CType::kBool:
|
||||||
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
||||||
fKey += inputs[offset];
|
|
||||||
b->add32(inputs[offset]);
|
b->add32(inputs[offset]);
|
||||||
}
|
}
|
||||||
++offset;
|
++offset;
|
||||||
@ -497,10 +481,6 @@ void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
|
|||||||
case SkSL::Layout::CType::kInt32: {
|
case SkSL::Layout::CType::kInt32: {
|
||||||
offset = SkAlign4(offset);
|
offset = SkAlign4(offset);
|
||||||
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
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));
|
b->add32(*(int32_t*)(inputs + offset));
|
||||||
}
|
}
|
||||||
offset += sizeof(int32_t);
|
offset += sizeof(int32_t);
|
||||||
@ -509,28 +489,33 @@ void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
|
|||||||
case SkSL::Layout::CType::kFloat: {
|
case SkSL::Layout::CType::kFloat: {
|
||||||
offset = SkAlign4(offset);
|
offset = SkAlign4(offset);
|
||||||
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
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));
|
b->add32(*(float*)(inputs + offset));
|
||||||
}
|
}
|
||||||
offset += sizeof(float);
|
offset += sizeof(float);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SkSL::Layout::CType::kFloat2:
|
case SkSL::Layout::CType::kFloat2:
|
||||||
copy_floats_key(inputs, b, v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag, 2,
|
offset = SkAlign4(offset);
|
||||||
&offset, &fKey);
|
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
||||||
|
memcpy(b->add32n(2), inputs + offset, 2 * sizeof(float));
|
||||||
|
}
|
||||||
|
offset += 2 * sizeof(float);
|
||||||
break;
|
break;
|
||||||
case SkSL::Layout::CType::kFloat3:
|
case SkSL::Layout::CType::kFloat3:
|
||||||
copy_floats_key(inputs, b, v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag, 3,
|
offset = SkAlign4(offset);
|
||||||
&offset, &fKey);
|
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
||||||
|
memcpy(b->add32n(3), inputs + offset, 3 * sizeof(float));
|
||||||
|
}
|
||||||
|
offset += 3 * sizeof(float);
|
||||||
break;
|
break;
|
||||||
case SkSL::Layout::CType::kSkPMColor:
|
case SkSL::Layout::CType::kSkPMColor:
|
||||||
case SkSL::Layout::CType::kSkPMColor4f:
|
case SkSL::Layout::CType::kSkPMColor4f:
|
||||||
case SkSL::Layout::CType::kSkRect:
|
case SkSL::Layout::CType::kSkRect:
|
||||||
copy_floats_key(inputs, b, v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag, 4,
|
offset = SkAlign4(offset);
|
||||||
&offset, &fKey);
|
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
||||||
|
memcpy(b->add32n(4), inputs + offset, 4 * sizeof(float));
|
||||||
|
}
|
||||||
|
offset += 4 * sizeof(float);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// unsupported input var type
|
// unsupported input var type
|
||||||
@ -566,7 +551,7 @@ sk_sp<GrSkSLFPFactory> GrSkSLFPFactoryCache::findOrCreate(int index, const char*
|
|||||||
|
|
||||||
sk_sp<GrSkSLFPFactory> factory = this->get(index);
|
sk_sp<GrSkSLFPFactory> factory = this->get(index);
|
||||||
if (!factory) {
|
if (!factory) {
|
||||||
factory = sk_sp<GrSkSLFPFactory>(new GrSkSLFPFactory(name, fShaderCaps.get(), skSL));
|
factory = sk_sp<GrSkSLFPFactory>(new GrSkSLFPFactory(name, skSL));
|
||||||
this->set(index, factory);
|
this->set(index, factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ public:
|
|||||||
std::unique_ptr<GrFragmentProcessor> clone() const override;
|
std::unique_ptr<GrFragmentProcessor> clone() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache,
|
GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, sk_sp<const GrShaderCaps> shaderCaps,
|
||||||
int fIndex, const char* name, const char* sksl,
|
int fIndex, const char* name, const char* sksl,
|
||||||
SkString skslString, const void* inputs, size_t inputSize, const SkMatrix* matrix);
|
SkString skslString, const void* inputs, size_t inputSize, const SkMatrix* matrix);
|
||||||
|
|
||||||
@ -125,6 +125,7 @@ private:
|
|||||||
void createFactory() const;
|
void createFactory() const;
|
||||||
|
|
||||||
sk_sp<GrSkSLFPFactoryCache> fFactoryCache;
|
sk_sp<GrSkSLFPFactoryCache> fFactoryCache;
|
||||||
|
sk_sp<const GrShaderCaps> fShaderCaps;
|
||||||
|
|
||||||
mutable sk_sp<GrSkSLFPFactory> fFactory;
|
mutable sk_sp<GrSkSLFPFactory> fFactory;
|
||||||
|
|
||||||
@ -148,8 +149,6 @@ private:
|
|||||||
|
|
||||||
GrCoordTransform fCoordTransform;
|
GrCoordTransform fCoordTransform;
|
||||||
|
|
||||||
mutable SkSL::String fKey;
|
|
||||||
|
|
||||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
|
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
|
||||||
|
|
||||||
typedef GrFragmentProcessor INHERITED;
|
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 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.
|
* 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,
|
std::unique_ptr<SkSL::Program> getSpecialization(const void* inputs, size_t inputSize);
|
||||||
size_t inputSize);
|
|
||||||
|
|
||||||
const char* fName;
|
const char* fName;
|
||||||
|
|
||||||
@ -185,8 +183,6 @@ public:
|
|||||||
|
|
||||||
std::vector<const SkSL::Variable*> fInAndUniformVars;
|
std::vector<const SkSL::Variable*> fInAndUniformVars;
|
||||||
|
|
||||||
std::unordered_map<SkSL::String, std::unique_ptr<const SkSL::Program>> fSpecializations;
|
|
||||||
|
|
||||||
friend class GrSkSLFP;
|
friend class GrSkSLFP;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user