Broke DSLWriter into two separate classes
As DSLWriter evolved, it ended up performing two unrelated duties: 1. Holding per-thread state which is referenced throughout SkSL (including non-DSL code) 2. DSL-specific utility functions There's no reason for those to be contained in the same class, and there's also no reason the per-thread state should be held in a DSL-specific class. This breaks out an SkSL::ThreadContext class to hold the state info, leaving the DSL utility functions behind in DSLWriter (which should perhaps be renamed, but that's a job for a future CL). Change-Id: Iccd45314bd9b37d4a1d3e27920e32a50c0b07d7c Reviewed-on: https://skia-review.googlesource.com/c/skia/+/456736 Commit-Queue: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
97bf72869a
commit
c845272b4e
@ -75,6 +75,8 @@ skia_sksl_sources = [
|
||||
"$_src/sksl/SkSLSampleUsage.cpp",
|
||||
"$_src/sksl/SkSLString.cpp",
|
||||
"$_src/sksl/SkSLStringStream.h",
|
||||
"$_src/sksl/SkSLThreadContext.cpp",
|
||||
"$_src/sksl/SkSLThreadContext.h",
|
||||
"$_src/sksl/SkSLUtil.cpp",
|
||||
"$_src/sksl/SkSLUtil.h",
|
||||
"$_src/sksl/analysis/SkSLCanExitWithoutReturningValue.cpp",
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "src/gpu/glsl/GrGLSLBlend.h"
|
||||
#include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h"
|
||||
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/ir/SkSLVarDeclarations.h"
|
||||
|
||||
GrGLSLShaderBuilder::GrGLSLShaderBuilder(GrGLSLProgramBuilder* program)
|
||||
@ -90,7 +90,7 @@ void GrGLSLShaderBuilder::emitFunctionPrototype(const char* declaration) {
|
||||
}
|
||||
|
||||
void GrGLSLShaderBuilder::codeAppend(std::unique_ptr<SkSL::Statement> stmt) {
|
||||
SkASSERT(SkSL::dsl::DSLWriter::CurrentProcessor());
|
||||
SkASSERT(SkSL::ThreadContext::CurrentProcessor());
|
||||
SkASSERT(stmt);
|
||||
this->codeAppend(stmt->description().c_str());
|
||||
if (stmt->is<SkSL::VarDeclaration>()) {
|
||||
|
@ -21,9 +21,7 @@
|
||||
class GrGLSLColorSpaceXformHelper;
|
||||
|
||||
namespace SkSL {
|
||||
namespace dsl {
|
||||
class DSLWriter;
|
||||
}
|
||||
class ThreadContext;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -290,6 +288,6 @@ protected:
|
||||
friend class GrGLPathProgramBuilder; // to access fInputs.
|
||||
friend class GrVkPipelineStateBuilder;
|
||||
friend class GrMtlPipelineStateBuilder;
|
||||
friend class SkSL::dsl::DSLWriter;
|
||||
friend class SkSL::ThreadContext;
|
||||
};
|
||||
#endif
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "src/sksl/SkSLOperators.h"
|
||||
#include "src/sksl/SkSLProgramSettings.h"
|
||||
#include "src/sksl/SkSLRehydrator.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/codegen/SkSLGLSLCodeGenerator.h"
|
||||
#include "src/sksl/codegen/SkSLMetalCodeGenerator.h"
|
||||
#include "src/sksl/codegen/SkSLSPIRVCodeGenerator.h"
|
||||
@ -539,7 +540,7 @@ bool Compiler::toSPIRV(Program& program, OutputStream& out) {
|
||||
settings.fDSLUseMemoryPool = false;
|
||||
dsl::Start(this, program.fConfig->fKind, settings);
|
||||
dsl::SetErrorReporter(&fErrorReporter);
|
||||
dsl::DSLWriter::IRGenerator().fSymbolTable = program.fSymbols;
|
||||
ThreadContext::IRGenerator().fSymbolTable = program.fSymbols;
|
||||
#ifdef SK_ENABLE_SPIRV_VALIDATION
|
||||
StringStream buffer;
|
||||
SPIRVCodeGenerator cg(fContext.get(), &program, &buffer);
|
||||
|
@ -265,8 +265,8 @@ private:
|
||||
friend class AutoSource;
|
||||
friend class ::SkSLCompileBench;
|
||||
friend class DSLParser;
|
||||
friend class ThreadContext;
|
||||
friend class dsl::DSLCore;
|
||||
friend class dsl::DSLWriter;
|
||||
};
|
||||
|
||||
} // namespace SkSL
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "include/private/SkSLString.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/dsl/priv/DSL_priv.h"
|
||||
|
||||
@ -230,7 +231,7 @@ SkSL::LoadedModule DSLParser::moduleInheritingFrom(SkSL::ParsedModule baseModule
|
||||
this->declarations();
|
||||
CurrentSymbolTable()->takeOwnershipOfString(std::move(*fText));
|
||||
SkSL::LoadedModule result{ fKind, CurrentSymbolTable(),
|
||||
std::move(DSLWriter::ProgramElements()) };
|
||||
std::move(ThreadContext::ProgramElements()) };
|
||||
errorReporter->setSource(nullptr);
|
||||
End();
|
||||
return result;
|
||||
|
@ -157,6 +157,7 @@ private:
|
||||
friend class AutoDisableInline;
|
||||
friend class Compiler;
|
||||
friend class DSLParser;
|
||||
friend class ThreadContext;
|
||||
friend class dsl::DSLCore;
|
||||
friend class dsl::DSLExpression;
|
||||
friend class dsl::DSLFunction;
|
||||
|
152
src/sksl/SkSLThreadContext.cpp
Normal file
152
src/sksl/SkSLThreadContext.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
|
||||
#include "include/sksl/DSLSymbols.h"
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLIRGenerator.h"
|
||||
#include "src/sksl/SkSLIntrinsicMap.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
ThreadContext::ThreadContext(SkSL::Compiler* compiler, SkSL::ProgramKind kind,
|
||||
const SkSL::ProgramSettings& settings, SkSL::ParsedModule module, bool isModule)
|
||||
: fCompiler(compiler)
|
||||
, fOldErrorReporter(*fCompiler->fContext->fErrors)
|
||||
, fSettings(settings) {
|
||||
fOldModifiersPool = fCompiler->fContext->fModifiersPool;
|
||||
|
||||
fOldConfig = fCompiler->fContext->fConfig;
|
||||
|
||||
if (!isModule) {
|
||||
if (compiler->context().fCaps.useNodePools() && settings.fDSLUseMemoryPool) {
|
||||
fPool = Pool::Create();
|
||||
fPool->attachToThread();
|
||||
}
|
||||
fModifiersPool = std::make_unique<SkSL::ModifiersPool>();
|
||||
fCompiler->fContext->fModifiersPool = fModifiersPool.get();
|
||||
}
|
||||
|
||||
fConfig = std::make_unique<SkSL::ProgramConfig>();
|
||||
fConfig->fKind = kind;
|
||||
fConfig->fSettings = settings;
|
||||
fConfig->fIsBuiltinCode = isModule;
|
||||
fCompiler->fContext->fConfig = fConfig.get();
|
||||
fCompiler->fContext->fErrors = &fDefaultErrorReporter;
|
||||
fCompiler->fContext->fIntrinsics = module.fIntrinsics.get();
|
||||
if (fCompiler->fContext->fIntrinsics) {
|
||||
fCompiler->fContext->fIntrinsics->resetAlreadyIncluded();
|
||||
}
|
||||
|
||||
fCompiler->fIRGenerator->start(module, &fProgramElements, &fSharedElements);
|
||||
}
|
||||
|
||||
ThreadContext::~ThreadContext() {
|
||||
if (SymbolTable()) {
|
||||
fCompiler->fIRGenerator->finish();
|
||||
fProgramElements.clear();
|
||||
} else {
|
||||
// We should only be here with a null symbol table if ReleaseProgram was called
|
||||
SkASSERT(fProgramElements.empty());
|
||||
}
|
||||
fCompiler->fContext->fErrors = &fOldErrorReporter;
|
||||
fCompiler->fContext->fConfig = fOldConfig;
|
||||
fCompiler->fContext->fModifiersPool = fOldModifiersPool;
|
||||
if (fPool) {
|
||||
fPool->detachFromThread();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SkSL::IRGenerator& ThreadContext::IRGenerator() {
|
||||
return *Compiler().fIRGenerator;
|
||||
}
|
||||
|
||||
SkSL::Context& ThreadContext::Context() {
|
||||
return Compiler().context();
|
||||
}
|
||||
|
||||
SkSL::ProgramSettings& ThreadContext::Settings() {
|
||||
return Context().fConfig->fSettings;
|
||||
}
|
||||
|
||||
SkSL::Program::Inputs& ThreadContext::Inputs() {
|
||||
return IRGenerator().fInputs;
|
||||
}
|
||||
|
||||
const std::shared_ptr<SkSL::SymbolTable>& ThreadContext::SymbolTable() {
|
||||
return IRGenerator().fSymbolTable;
|
||||
}
|
||||
|
||||
const SkSL::Modifiers* ThreadContext::Modifiers(const SkSL::Modifiers& modifiers) {
|
||||
return Context().fModifiersPool->add(modifiers);
|
||||
}
|
||||
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
void ThreadContext::StartFragmentProcessor(GrFragmentProcessor::ProgramImpl* processor,
|
||||
GrFragmentProcessor::ProgramImpl::EmitArgs* emitArgs) {
|
||||
ThreadContext& instance = ThreadContext::Instance();
|
||||
instance.fStack.push({processor, emitArgs, StatementArray{}});
|
||||
CurrentEmitArgs()->fFragBuilder->fDeclarations.swap(instance.fStack.top().fSavedDeclarations);
|
||||
dsl::PushSymbolTable();
|
||||
}
|
||||
|
||||
void ThreadContext::EndFragmentProcessor() {
|
||||
ThreadContext& instance = Instance();
|
||||
SkASSERT(!instance.fStack.empty());
|
||||
CurrentEmitArgs()->fFragBuilder->fDeclarations.swap(instance.fStack.top().fSavedDeclarations);
|
||||
instance.fStack.pop();
|
||||
dsl::PopSymbolTable();
|
||||
}
|
||||
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
|
||||
void ThreadContext::SetErrorReporter(ErrorReporter* errorReporter) {
|
||||
SkASSERT(errorReporter);
|
||||
Context().fErrors = errorReporter;
|
||||
}
|
||||
|
||||
void ThreadContext::ReportError(skstd::string_view msg, PositionInfo info) {
|
||||
GetErrorReporter().error(msg, info);
|
||||
}
|
||||
|
||||
void ThreadContext::DefaultErrorReporter::handleError(skstd::string_view msg, PositionInfo pos) {
|
||||
if (pos.line() > -1) {
|
||||
SK_ABORT("error: %s: %d: %.*sNo SkSL error reporter configured, treating this as a fatal "
|
||||
"error\n", pos.file_name(), pos.line(), (int)msg.length(), msg.data());
|
||||
} else {
|
||||
SK_ABORT("error: %.*s\nNo SkSL error reporter configured, treating this as a fatal error\n",
|
||||
(int)msg.length(), msg.data());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ThreadContext::ReportErrors(PositionInfo pos) {
|
||||
GetErrorReporter().reportPendingErrors(pos);
|
||||
}
|
||||
|
||||
thread_local ThreadContext* instance = nullptr;
|
||||
|
||||
bool ThreadContext::IsActive() {
|
||||
return instance != nullptr;
|
||||
}
|
||||
|
||||
ThreadContext& ThreadContext::Instance() {
|
||||
SkASSERTF(instance, "dsl::Start() has not been called");
|
||||
return *instance;
|
||||
}
|
||||
|
||||
void ThreadContext::SetInstance(std::unique_ptr<ThreadContext> newInstance) {
|
||||
SkASSERT((instance == nullptr) != (newInstance == nullptr));
|
||||
delete instance;
|
||||
instance = newInstance.release();
|
||||
}
|
||||
|
||||
} // namespace SkSL
|
213
src/sksl/SkSLThreadContext.h
Normal file
213
src/sksl/SkSLThreadContext.h
Normal file
@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright 2021 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_THREADCONTEXT
|
||||
#define SKSL_THREADCONTEXT
|
||||
|
||||
#include "include/core/SkStringView.h"
|
||||
#include "include/private/SkSLModifiers.h"
|
||||
#include "src/sksl/SkSLMangler.h"
|
||||
#include "src/sksl/ir/SkSLProgram.h"
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
#include "src/gpu/GrFragmentProcessor.h"
|
||||
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
#include <list>
|
||||
#include <stack>
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
class Compiler;
|
||||
class Context;
|
||||
class IRGenerator;
|
||||
struct ParsedModule;
|
||||
class ProgramElement;
|
||||
class SymbolTable;
|
||||
class Type;
|
||||
class Variable;
|
||||
|
||||
namespace dsl {
|
||||
|
||||
class DSLCore;
|
||||
class DSLWriter;
|
||||
|
||||
} // namespace dsl
|
||||
|
||||
/**
|
||||
* Thread-safe class that tracks per-thread state associated with SkSL output.
|
||||
*/
|
||||
class ThreadContext {
|
||||
public:
|
||||
ThreadContext(SkSL::Compiler* compiler, SkSL::ProgramKind kind,
|
||||
const SkSL::ProgramSettings& settings, SkSL::ParsedModule module, bool isModule);
|
||||
|
||||
~ThreadContext();
|
||||
|
||||
/**
|
||||
* Returns true if the DSL has been started.
|
||||
*/
|
||||
static bool IsActive();
|
||||
|
||||
/**
|
||||
* Returns the Compiler used by DSL operations in the current thread.
|
||||
*/
|
||||
static SkSL::Compiler& Compiler() { return *Instance().fCompiler; }
|
||||
|
||||
/**
|
||||
* Returns the IRGenerator used by DSL operations in the current thread.
|
||||
*/
|
||||
static SkSL::IRGenerator& IRGenerator();
|
||||
|
||||
/**
|
||||
* Returns the Context used by DSL operations in the current thread.
|
||||
*/
|
||||
static SkSL::Context& Context();
|
||||
|
||||
/**
|
||||
* Returns the Settings used by DSL operations in the current thread.
|
||||
*/
|
||||
static SkSL::ProgramSettings& Settings();
|
||||
|
||||
/**
|
||||
* Returns the Program::Inputs used by the current thread.
|
||||
*/
|
||||
static SkSL::Program::Inputs& Inputs();
|
||||
|
||||
/**
|
||||
* Returns the collection to which DSL program elements in this thread should be appended.
|
||||
*/
|
||||
static std::vector<std::unique_ptr<SkSL::ProgramElement>>& ProgramElements() {
|
||||
return Instance().fProgramElements;
|
||||
}
|
||||
|
||||
static std::vector<const ProgramElement*>& SharedElements() {
|
||||
return Instance().fSharedElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SymbolTable of the current thread's IRGenerator.
|
||||
*/
|
||||
static const std::shared_ptr<SkSL::SymbolTable>& SymbolTable();
|
||||
|
||||
/**
|
||||
* Returns the current memory pool.
|
||||
*/
|
||||
static std::unique_ptr<Pool>& MemoryPool() { return Instance().fPool; }
|
||||
|
||||
/**
|
||||
* Returns the current modifiers pool.
|
||||
*/
|
||||
static std::unique_ptr<ModifiersPool>& GetModifiersPool() { return Instance().fModifiersPool; }
|
||||
|
||||
/**
|
||||
* Returns the current ProgramConfig.
|
||||
*/
|
||||
static std::unique_ptr<ProgramConfig>& GetProgramConfig() { return Instance().fConfig; }
|
||||
|
||||
static bool IsModule() { return GetProgramConfig()->fIsBuiltinCode; }
|
||||
|
||||
/**
|
||||
* Returns the final pointer to a pooled Modifiers object that should be used to represent the
|
||||
* given modifiers.
|
||||
*/
|
||||
static const SkSL::Modifiers* Modifiers(const SkSL::Modifiers& modifiers);
|
||||
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
/**
|
||||
* Returns the fragment processor for which DSL output is being generated for the current
|
||||
* thread.
|
||||
*/
|
||||
static GrFragmentProcessor::ProgramImpl* CurrentProcessor() {
|
||||
SkASSERTF(!Instance().fStack.empty(), "This feature requires a FragmentProcessor");
|
||||
return Instance().fStack.top().fProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the EmitArgs for fragment processor output in the current thread.
|
||||
*/
|
||||
static GrFragmentProcessor::ProgramImpl::EmitArgs* CurrentEmitArgs() {
|
||||
SkASSERTF(!Instance().fStack.empty(), "This feature requires a FragmentProcessor");
|
||||
return Instance().fStack.top().fEmitArgs;
|
||||
}
|
||||
|
||||
static bool InFragmentProcessor() {
|
||||
return !Instance().fStack.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes a new processor / emitArgs pair for the current thread.
|
||||
*/
|
||||
static void StartFragmentProcessor(GrFragmentProcessor::ProgramImpl* processor,
|
||||
GrFragmentProcessor::ProgramImpl::EmitArgs* emitArgs);
|
||||
|
||||
/**
|
||||
* Pops the processor / emitArgs pair associated with the current thread.
|
||||
*/
|
||||
static void EndFragmentProcessor();
|
||||
#else
|
||||
static bool InFragmentProcessor() {
|
||||
return false;
|
||||
}
|
||||
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
|
||||
/**
|
||||
* Returns the ErrorReporter associated with the current thread. This object will be notified
|
||||
* when any DSL errors occur.
|
||||
*/
|
||||
static ErrorReporter& GetErrorReporter() {
|
||||
return *Context().fErrors;
|
||||
}
|
||||
|
||||
static void SetErrorReporter(ErrorReporter* errorReporter);
|
||||
|
||||
/**
|
||||
* Notifies the current ErrorReporter that an error has occurred. The default error handler
|
||||
* prints the message to stderr and aborts.
|
||||
*/
|
||||
static void ReportError(skstd::string_view msg, PositionInfo info = PositionInfo::Capture());
|
||||
|
||||
/**
|
||||
* Forwards any pending errors to the DSL ErrorReporter.
|
||||
*/
|
||||
static void ReportErrors(PositionInfo pos);
|
||||
|
||||
static ThreadContext& Instance();
|
||||
|
||||
static void SetInstance(std::unique_ptr<ThreadContext> instance);
|
||||
|
||||
private:
|
||||
class DefaultErrorReporter : public ErrorReporter {
|
||||
void handleError(skstd::string_view msg, PositionInfo pos) override;
|
||||
};
|
||||
|
||||
std::unique_ptr<SkSL::ProgramConfig> fConfig;
|
||||
std::unique_ptr<SkSL::ModifiersPool> fModifiersPool;
|
||||
SkSL::Compiler* fCompiler;
|
||||
std::unique_ptr<Pool> fPool;
|
||||
SkSL::ProgramConfig* fOldConfig;
|
||||
SkSL::ModifiersPool* fOldModifiersPool;
|
||||
std::vector<std::unique_ptr<SkSL::ProgramElement>> fProgramElements;
|
||||
std::vector<const SkSL::ProgramElement*> fSharedElements;
|
||||
DefaultErrorReporter fDefaultErrorReporter;
|
||||
ErrorReporter& fOldErrorReporter;
|
||||
ProgramSettings fSettings;
|
||||
Mangler fMangler;
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
struct StackFrame {
|
||||
GrFragmentProcessor::ProgramImpl* fProcessor;
|
||||
GrFragmentProcessor::ProgramImpl::EmitArgs* fEmitArgs;
|
||||
SkSL::StatementArray fSavedDeclarations;
|
||||
};
|
||||
std::stack<StackFrame, std::list<StackFrame>> fStack;
|
||||
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
|
||||
friend class dsl::DSLCore;
|
||||
friend class dsl::DSLWriter;
|
||||
};
|
||||
|
||||
} // namespace SkSL
|
||||
|
||||
#endif
|
@ -12,7 +12,7 @@
|
||||
#include "include/sksl/DSLCore.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLOperators.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/ir/SkSLBlock.h"
|
||||
#include "src/sksl/ir/SkSLConstructorArrayCast.h"
|
||||
#include "src/sksl/ir/SkSLExpressionStatement.h"
|
||||
@ -1095,8 +1095,8 @@ SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIn
|
||||
this->writeWord(fn, out);
|
||||
this->addRTFlipUniform(c.fLine);
|
||||
using namespace dsl;
|
||||
DSLExpression rtFlip(DSLWriter::IRGenerator().convertIdentifier(/*line=*/-1,
|
||||
SKSL_RTFLIP_NAME));
|
||||
DSLExpression rtFlip(ThreadContext::IRGenerator().convertIdentifier(/*line=*/-1,
|
||||
SKSL_RTFLIP_NAME));
|
||||
SpvId rtFlipY = this->vectorize(*rtFlip.y().release(), callType.columns(), out);
|
||||
SpvId flipped = this->nextId(&callType);
|
||||
this->writeInstruction(SpvOpFMul, this->getType(callType), flipped, result, rtFlipY,
|
||||
@ -2111,12 +2111,12 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
|
||||
// Use sk_RTAdjust to compute the flipped coordinate
|
||||
using namespace dsl;
|
||||
const char* DEVICE_COORDS_NAME = "__device_FragCoords";
|
||||
SymbolTable& symbols = *dsl::DSLWriter::SymbolTable();
|
||||
SymbolTable& symbols = *ThreadContext::SymbolTable();
|
||||
// Use a uniform to flip the Y coordinate. The new expression will be written in
|
||||
// terms of __device_FragCoords, which is a fake variable that means "access the
|
||||
// underlying fragcoords directly without flipping it".
|
||||
DSLExpression rtFlip(DSLWriter::IRGenerator().convertIdentifier(/*line=*/-1,
|
||||
SKSL_RTFLIP_NAME));
|
||||
DSLExpression rtFlip(ThreadContext::IRGenerator().convertIdentifier(/*line=*/-1,
|
||||
SKSL_RTFLIP_NAME));
|
||||
if (!symbols[DEVICE_COORDS_NAME]) {
|
||||
AutoAttachPoolToThread attach(fProgram.fPool.get());
|
||||
Modifiers modifiers;
|
||||
@ -2146,12 +2146,12 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
|
||||
this->addRTFlipUniform(ref.fLine);
|
||||
using namespace dsl;
|
||||
const char* DEVICE_CLOCKWISE_NAME = "__device_Clockwise";
|
||||
SymbolTable& symbols = *dsl::DSLWriter::SymbolTable();
|
||||
SymbolTable& symbols = *ThreadContext::SymbolTable();
|
||||
// Use a uniform to flip the Y coordinate. The new expression will be written in
|
||||
// terms of __device_Clockwise, which is a fake variable that means "access the
|
||||
// underlying FrontFacing directly".
|
||||
DSLExpression rtFlip(DSLWriter::IRGenerator().convertIdentifier(/*line=*/-1,
|
||||
SKSL_RTFLIP_NAME));
|
||||
DSLExpression rtFlip(ThreadContext::IRGenerator().convertIdentifier(/*line=*/-1,
|
||||
SKSL_RTFLIP_NAME));
|
||||
if (!symbols[DEVICE_CLOCKWISE_NAME]) {
|
||||
AutoAttachPoolToThread attach(fProgram.fPool.get());
|
||||
Modifiers modifiers;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "include/sksl/DSLVar.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLIRGenerator.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/ir/SkSLBreakStatement.h"
|
||||
#include "src/sksl/ir/SkSLContinueStatement.h"
|
||||
@ -37,46 +38,45 @@ void Start(SkSL::Compiler* compiler, ProgramKind kind) {
|
||||
}
|
||||
|
||||
void Start(SkSL::Compiler* compiler, ProgramKind kind, const ProgramSettings& settings) {
|
||||
DSLWriter::SetInstance(std::make_unique<DSLWriter>(compiler, kind, settings,
|
||||
compiler->moduleForProgramKind(kind),
|
||||
/*isModule=*/false));
|
||||
ThreadContext::SetInstance(std::make_unique<ThreadContext>(compiler, kind, settings,
|
||||
compiler->moduleForProgramKind(kind), /*isModule=*/false));
|
||||
}
|
||||
|
||||
void StartModule(SkSL::Compiler* compiler, ProgramKind kind, const ProgramSettings& settings,
|
||||
SkSL::ParsedModule baseModule) {
|
||||
DSLWriter::SetInstance(std::make_unique<DSLWriter>(compiler, kind, settings,
|
||||
baseModule, /*isModule=*/true));
|
||||
ThreadContext::SetInstance(std::make_unique<ThreadContext>(compiler, kind, settings,
|
||||
baseModule, /*isModule=*/true));
|
||||
}
|
||||
|
||||
void End() {
|
||||
SkASSERTF(!DSLWriter::InFragmentProcessor(),
|
||||
SkASSERTF(!ThreadContext::InFragmentProcessor(),
|
||||
"more calls to StartFragmentProcessor than to EndFragmentProcessor");
|
||||
DSLWriter::SetInstance(nullptr);
|
||||
ThreadContext::SetInstance(nullptr);
|
||||
}
|
||||
|
||||
ErrorReporter& GetErrorReporter() {
|
||||
return DSLWriter::GetErrorReporter();
|
||||
return ThreadContext::GetErrorReporter();
|
||||
}
|
||||
|
||||
void SetErrorReporter(ErrorReporter* errorReporter) {
|
||||
SkASSERT(errorReporter);
|
||||
DSLWriter::SetErrorReporter(errorReporter);
|
||||
ThreadContext::SetErrorReporter(errorReporter);
|
||||
}
|
||||
|
||||
class DSLCore {
|
||||
public:
|
||||
static std::unique_ptr<SkSL::Program> ReleaseProgram(std::unique_ptr<String> source) {
|
||||
DSLWriter& instance = DSLWriter::Instance();
|
||||
SkSL::IRGenerator& ir = DSLWriter::IRGenerator();
|
||||
SkSL::Compiler& compiler = DSLWriter::Compiler();
|
||||
const SkSL::Context& context = DSLWriter::Context();
|
||||
ThreadContext& instance = ThreadContext::Instance();
|
||||
SkSL::IRGenerator& ir = ThreadContext::IRGenerator();
|
||||
SkSL::Compiler& compiler = ThreadContext::Compiler();
|
||||
const SkSL::Context& context = ThreadContext::Context();
|
||||
// Variables defined in the pre-includes need their declaring elements added to the program
|
||||
if (!context.fConfig->fIsBuiltinCode && context.fIntrinsics) {
|
||||
Transform::FindAndDeclareBuiltinVariables(DSLWriter::Context(),
|
||||
DSLWriter::GetProgramConfig()->fKind, DSLWriter::SharedElements());
|
||||
Transform::FindAndDeclareBuiltinVariables(ThreadContext::Context(),
|
||||
ThreadContext::GetProgramConfig()->fKind, ThreadContext::SharedElements());
|
||||
}
|
||||
IRGenerator::IRBundle bundle = ir.finish();
|
||||
Pool* pool = DSLWriter::Instance().fPool.get();
|
||||
Pool* pool = ThreadContext::Instance().fPool.get();
|
||||
auto result = std::make_unique<SkSL::Program>(std::move(source),
|
||||
std::move(instance.fConfig),
|
||||
compiler.fContext,
|
||||
@ -96,13 +96,13 @@ public:
|
||||
success = true;
|
||||
}
|
||||
if (!success) {
|
||||
DSLWriter::ReportErrors(PositionInfo());
|
||||
ThreadContext::ReportErrors(PositionInfo());
|
||||
}
|
||||
if (pool) {
|
||||
pool->detachFromThread();
|
||||
}
|
||||
SkASSERT(DSLWriter::ProgramElements().empty());
|
||||
SkASSERT(!DSLWriter::SymbolTable());
|
||||
SkASSERT(ThreadContext::ProgramElements().empty());
|
||||
SkASSERT(!ThreadContext::SymbolTable());
|
||||
return success ? std::move(result) : nullptr;
|
||||
}
|
||||
|
||||
@ -128,8 +128,8 @@ public:
|
||||
int unused[] = {0, (static_cast<void>(argArray.push_back(args.release())), 0)...};
|
||||
static_cast<void>(unused);
|
||||
|
||||
return SkSL::FunctionCall::Convert(DSLWriter::Context(), /*line=*/-1,
|
||||
DSLWriter::IRGenerator().convertIdentifier(-1, name), std::move(argArray));
|
||||
return SkSL::FunctionCall::Convert(ThreadContext::Context(), /*line=*/-1,
|
||||
ThreadContext::IRGenerator().convertIdentifier(-1, name), std::move(argArray));
|
||||
}
|
||||
|
||||
static DSLStatement Break(PositionInfo pos) {
|
||||
@ -141,13 +141,13 @@ public:
|
||||
}
|
||||
|
||||
static void Declare(const DSLModifiers& modifiers) {
|
||||
DSLWriter::ProgramElements().push_back(std::make_unique<SkSL::ModifiersDeclaration>(
|
||||
DSLWriter::Modifiers(modifiers.fModifiers)));
|
||||
ThreadContext::ProgramElements().push_back(std::make_unique<SkSL::ModifiersDeclaration>(
|
||||
ThreadContext::Modifiers(modifiers.fModifiers)));
|
||||
}
|
||||
|
||||
static DSLStatement Declare(DSLVar& var, PositionInfo pos) {
|
||||
if (var.fDeclared) {
|
||||
DSLWriter::ReportError("variable has already been declared", pos);
|
||||
ThreadContext::ReportError("variable has already been declared", pos);
|
||||
}
|
||||
var.fDeclared = true;
|
||||
return DSLWriter::Declaration(var);
|
||||
@ -163,20 +163,20 @@ public:
|
||||
|
||||
static void Declare(DSLGlobalVar& var, PositionInfo pos) {
|
||||
if (var.fDeclared) {
|
||||
DSLWriter::ReportError("variable has already been declared", pos);
|
||||
ThreadContext::ReportError("variable has already been declared", pos);
|
||||
}
|
||||
var.fDeclared = true;
|
||||
std::unique_ptr<SkSL::Statement> stmt = DSLWriter::Declaration(var);
|
||||
if (stmt) {
|
||||
if (!stmt->isEmpty()) {
|
||||
DSLWriter::ProgramElements().push_back(std::make_unique<SkSL::GlobalVarDeclaration>(
|
||||
std::move(stmt)));
|
||||
ThreadContext::ProgramElements().push_back(
|
||||
std::make_unique<SkSL::GlobalVarDeclaration>(std::move(stmt)));
|
||||
}
|
||||
} else if (var.fName == SkSL::Compiler::FRAGCOLOR_NAME) {
|
||||
// sk_FragColor can end up with a null declaration despite no error occurring due to
|
||||
// specific treatment in the compiler. Ignore the null and just grab the existing
|
||||
// variable from the symbol table.
|
||||
const SkSL::Symbol* alreadyDeclared = (*DSLWriter::SymbolTable())[var.fName];
|
||||
const SkSL::Symbol* alreadyDeclared = (*ThreadContext::SymbolTable())[var.fName];
|
||||
if (alreadyDeclared && alreadyDeclared->is<Variable>()) {
|
||||
var.fVar = &alreadyDeclared->as<Variable>();
|
||||
var.fInitialized = true;
|
||||
@ -195,20 +195,20 @@ public:
|
||||
}
|
||||
|
||||
static DSLPossibleStatement Do(DSLStatement stmt, DSLExpression test) {
|
||||
return DoStatement::Convert(DSLWriter::Context(), stmt.release(), test.release());
|
||||
return DoStatement::Convert(ThreadContext::Context(), stmt.release(), test.release());
|
||||
}
|
||||
|
||||
static DSLPossibleStatement For(DSLStatement initializer, DSLExpression test,
|
||||
DSLExpression next, DSLStatement stmt, PositionInfo pos) {
|
||||
return ForStatement::Convert(DSLWriter::Context(), pos.line(),
|
||||
return ForStatement::Convert(ThreadContext::Context(), pos.line(),
|
||||
initializer.releaseIfPossible(), test.releaseIfPossible(),
|
||||
next.releaseIfPossible(), stmt.release(),
|
||||
DSLWriter::SymbolTable());
|
||||
ThreadContext::SymbolTable());
|
||||
}
|
||||
|
||||
static DSLPossibleStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse,
|
||||
bool isStatic) {
|
||||
return IfStatement::Convert(DSLWriter::Context(), /*line=*/-1, isStatic, test.release(),
|
||||
return IfStatement::Convert(ThreadContext::Context(), /*line=*/-1, isStatic, test.release(),
|
||||
ifTrue.release(), ifFalse.releaseIfPossible());
|
||||
}
|
||||
|
||||
@ -225,34 +225,34 @@ public:
|
||||
if (baseType->isArray()) {
|
||||
baseType = &baseType->componentType();
|
||||
}
|
||||
DSLWriter::IRGenerator().checkVarDeclaration(pos.line(), field.fModifiers.fModifiers,
|
||||
baseType, Variable::Storage::kInterfaceBlock);
|
||||
ThreadContext::IRGenerator().checkVarDeclaration(pos.line(),
|
||||
field.fModifiers.fModifiers, baseType, Variable::Storage::kInterfaceBlock);
|
||||
GetErrorReporter().reportPendingErrors(field.fPosition);
|
||||
skslFields.push_back(SkSL::Type::Field(field.fModifiers.fModifiers, field.fName,
|
||||
&field.fType.skslType()));
|
||||
}
|
||||
const SkSL::Type* structType = DSLWriter::SymbolTable()->takeOwnershipOfSymbol(
|
||||
const SkSL::Type* structType = ThreadContext::SymbolTable()->takeOwnershipOfSymbol(
|
||||
SkSL::Type::MakeStructType(pos.line(), typeName, std::move(skslFields)));
|
||||
DSLType varType = arraySize > 0 ? Array(structType, arraySize) : DSLType(structType);
|
||||
DSLGlobalVar var(modifiers, varType, !varName.empty() ? varName : typeName, DSLExpression(),
|
||||
pos);
|
||||
// Interface blocks can't be declared, so we always need to mark the var declared ourselves.
|
||||
// We do this only when fDSLMarkVarDeclared is false, so we don't double-declare it.
|
||||
if (!DSLWriter::Settings().fDSLMarkVarsDeclared) {
|
||||
if (!ThreadContext::Settings().fDSLMarkVarsDeclared) {
|
||||
DSLWriter::MarkDeclared(var);
|
||||
}
|
||||
const SkSL::Variable* skslVar = DSLWriter::Var(var);
|
||||
if (skslVar) {
|
||||
auto intf = std::make_unique<SkSL::InterfaceBlock>(pos.line(),
|
||||
*skslVar, typeName, varName, arraySize, DSLWriter::SymbolTable());
|
||||
DSLWriter::IRGenerator().scanInterfaceBlock(*intf);
|
||||
DSLWriter::ProgramElements().push_back(std::move(intf));
|
||||
*skslVar, typeName, varName, arraySize, ThreadContext::SymbolTable());
|
||||
ThreadContext::IRGenerator().scanInterfaceBlock(*intf);
|
||||
ThreadContext::ProgramElements().push_back(std::move(intf));
|
||||
if (varName.empty()) {
|
||||
const std::vector<SkSL::Type::Field>& structFields = structType->fields();
|
||||
for (size_t i = 0; i < structFields.size(); ++i) {
|
||||
DSLWriter::SymbolTable()->add(std::make_unique<SkSL::Field>(pos.line(),
|
||||
skslVar,
|
||||
i));
|
||||
ThreadContext::SymbolTable()->add(std::make_unique<SkSL::Field>(pos.line(),
|
||||
skslVar,
|
||||
i));
|
||||
}
|
||||
} else {
|
||||
AddToSymbolTable(var);
|
||||
@ -272,7 +272,7 @@ public:
|
||||
|
||||
static DSLExpression Swizzle(DSLExpression base, SkSL::SwizzleComponent::Type a,
|
||||
PositionInfo pos) {
|
||||
return DSLExpression(Swizzle::Convert(DSLWriter::Context(), base.release(),
|
||||
return DSLExpression(Swizzle::Convert(ThreadContext::Context(), base.release(),
|
||||
ComponentArray{a}),
|
||||
pos);
|
||||
}
|
||||
@ -281,7 +281,7 @@ public:
|
||||
SkSL::SwizzleComponent::Type a,
|
||||
SkSL::SwizzleComponent::Type b,
|
||||
PositionInfo pos) {
|
||||
return DSLExpression(Swizzle::Convert(DSLWriter::Context(), base.release(),
|
||||
return DSLExpression(Swizzle::Convert(ThreadContext::Context(), base.release(),
|
||||
ComponentArray{a, b}),
|
||||
pos);
|
||||
}
|
||||
@ -291,7 +291,7 @@ public:
|
||||
SkSL::SwizzleComponent::Type b,
|
||||
SkSL::SwizzleComponent::Type c,
|
||||
PositionInfo pos) {
|
||||
return DSLExpression(Swizzle::Convert(DSLWriter::Context(), base.release(),
|
||||
return DSLExpression(Swizzle::Convert(ThreadContext::Context(), base.release(),
|
||||
ComponentArray{a, b, c}),
|
||||
pos);
|
||||
}
|
||||
@ -302,14 +302,14 @@ public:
|
||||
SkSL::SwizzleComponent::Type c,
|
||||
SkSL::SwizzleComponent::Type d,
|
||||
PositionInfo pos) {
|
||||
return DSLExpression(Swizzle::Convert(DSLWriter::Context(), base.release(),
|
||||
return DSLExpression(Swizzle::Convert(ThreadContext::Context(), base.release(),
|
||||
ComponentArray{a,b,c,d}),
|
||||
pos);
|
||||
}
|
||||
|
||||
static DSLPossibleExpression Select(DSLExpression test, DSLExpression ifTrue,
|
||||
DSLExpression ifFalse) {
|
||||
return TernaryExpression::Convert(DSLWriter::Context(), test.release(),
|
||||
return TernaryExpression::Convert(ThreadContext::Context(), test.release(),
|
||||
ifTrue.release(), ifFalse.release());
|
||||
}
|
||||
|
||||
@ -324,14 +324,14 @@ public:
|
||||
caseBlocks.push_back(SkSL::Block::Make(/*line=*/-1,
|
||||
std::move(c.fStatements), /*symbols=*/nullptr, /*isScope=*/false));
|
||||
}
|
||||
return SwitchStatement::Convert(DSLWriter::Context(), /*line=*/-1, isStatic,
|
||||
return SwitchStatement::Convert(ThreadContext::Context(), /*line=*/-1, isStatic,
|
||||
value.release(), std::move(values), std::move(caseBlocks),
|
||||
DSLWriter::SymbolTable());
|
||||
ThreadContext::SymbolTable());
|
||||
}
|
||||
|
||||
static DSLPossibleStatement While(DSLExpression test, DSLStatement stmt) {
|
||||
return ForStatement::ConvertWhile(DSLWriter::Context(), /*line=*/-1, test.release(),
|
||||
stmt.release(), DSLWriter::SymbolTable());
|
||||
return ForStatement::ConvertWhile(ThreadContext::Context(), /*line=*/-1, test.release(),
|
||||
stmt.release(), ThreadContext::SymbolTable());
|
||||
}
|
||||
};
|
||||
|
||||
@ -352,8 +352,8 @@ DSLExpression sk_Position() {
|
||||
}
|
||||
|
||||
void AddExtension(skstd::string_view name, PositionInfo pos) {
|
||||
DSLWriter::ProgramElements().push_back(std::make_unique<SkSL::Extension>(pos.line(), name));
|
||||
DSLWriter::ReportErrors(pos);
|
||||
ThreadContext::ProgramElements().push_back(std::make_unique<SkSL::Extension>(pos.line(), name));
|
||||
ThreadContext::ReportErrors(pos);
|
||||
}
|
||||
|
||||
DSLStatement Break(PositionInfo pos) {
|
||||
@ -365,10 +365,11 @@ DSLStatement Continue(PositionInfo pos) {
|
||||
}
|
||||
|
||||
void Declare(const DSLModifiers& modifiers, PositionInfo pos) {
|
||||
SkSL::ProgramKind kind = DSLWriter::GetProgramConfig()->fKind;
|
||||
SkSL::ProgramKind kind = ThreadContext::GetProgramConfig()->fKind;
|
||||
if (kind != ProgramKind::kFragment &&
|
||||
kind != ProgramKind::kVertex) {
|
||||
DSLWriter::ReportError("layout qualifiers are not allowed in this kind of program", pos);
|
||||
ThreadContext::ReportError("layout qualifiers are not allowed in this kind of program",
|
||||
pos);
|
||||
return;
|
||||
}
|
||||
DSLCore::Declare(modifiers);
|
||||
@ -403,8 +404,8 @@ void Declare(SkTArray<DSLGlobalVar>& vars, PositionInfo pos) {
|
||||
}
|
||||
|
||||
DSLStatement Discard(PositionInfo pos) {
|
||||
if (DSLWriter::GetProgramConfig()->fKind != ProgramKind::kFragment) {
|
||||
DSLWriter::ReportError("discard statement is only permitted in fragment shaders", pos);
|
||||
if (ThreadContext::GetProgramConfig()->fKind != ProgramKind::kFragment) {
|
||||
ThreadContext::ReportError("discard statement is only permitted in fragment shaders", pos);
|
||||
}
|
||||
return DSLCore::Discard(pos);
|
||||
}
|
||||
@ -428,10 +429,10 @@ DSLStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse, P
|
||||
DSLGlobalVar InterfaceBlock(const DSLModifiers& modifiers, skstd::string_view typeName,
|
||||
SkTArray<DSLField> fields, skstd::string_view varName, int arraySize,
|
||||
PositionInfo pos) {
|
||||
SkSL::ProgramKind kind = DSLWriter::GetProgramConfig()->fKind;
|
||||
SkSL::ProgramKind kind = ThreadContext::GetProgramConfig()->fKind;
|
||||
if (kind != ProgramKind::kFragment &&
|
||||
kind != ProgramKind::kVertex) {
|
||||
DSLWriter::ReportError("interface blocks are not allowed in this kind of program", pos);
|
||||
ThreadContext::ReportError("interface blocks are not allowed in this kind of program", pos);
|
||||
return DSLGlobalVar();
|
||||
}
|
||||
return DSLCore::InterfaceBlock(modifiers, typeName, std::move(fields), varName, arraySize, pos);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "include/sksl/DSLVar.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLIRGenerator.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/ir/SkSLBinaryExpression.h"
|
||||
#include "src/sksl/ir/SkSLFieldAccess.h"
|
||||
@ -42,35 +43,35 @@ DSLExpression::DSLExpression(std::unique_ptr<SkSL::Expression> expression)
|
||||
}
|
||||
|
||||
DSLExpression::DSLExpression(float value, PositionInfo pos)
|
||||
: fExpression(SkSL::Literal::MakeFloat(DSLWriter::Context(),
|
||||
: fExpression(SkSL::Literal::MakeFloat(ThreadContext::Context(),
|
||||
pos.line(),
|
||||
value)) {
|
||||
if (!isfinite(value)) {
|
||||
if (isinf(value)) {
|
||||
DSLWriter::ReportError("floating point value is infinite");
|
||||
ThreadContext::ReportError("floating point value is infinite");
|
||||
} else if (isnan(value)) {
|
||||
DSLWriter::ReportError("floating point value is NaN");
|
||||
ThreadContext::ReportError("floating point value is NaN");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DSLExpression::DSLExpression(int value, PositionInfo pos)
|
||||
: fExpression(SkSL::Literal::MakeInt(DSLWriter::Context(),
|
||||
: fExpression(SkSL::Literal::MakeInt(ThreadContext::Context(),
|
||||
pos.line(),
|
||||
value)) {}
|
||||
|
||||
DSLExpression::DSLExpression(int64_t value, PositionInfo pos)
|
||||
: fExpression(SkSL::Literal::MakeInt(DSLWriter::Context(),
|
||||
: fExpression(SkSL::Literal::MakeInt(ThreadContext::Context(),
|
||||
pos.line(),
|
||||
value)) {}
|
||||
|
||||
DSLExpression::DSLExpression(unsigned int value, PositionInfo pos)
|
||||
: fExpression(SkSL::Literal::MakeInt(DSLWriter::Context(),
|
||||
: fExpression(SkSL::Literal::MakeInt(ThreadContext::Context(),
|
||||
pos.line(),
|
||||
value)) {}
|
||||
|
||||
DSLExpression::DSLExpression(bool value, PositionInfo pos)
|
||||
: fExpression(SkSL::Literal::MakeBool(DSLWriter::Context(),
|
||||
: fExpression(SkSL::Literal::MakeBool(ThreadContext::Context(),
|
||||
pos.line(),
|
||||
value)) {}
|
||||
|
||||
@ -83,27 +84,27 @@ DSLExpression::DSLExpression(DSLVarBase&& var, PositionInfo pos)
|
||||
: DSLExpression(var) {}
|
||||
|
||||
DSLExpression::DSLExpression(DSLPossibleExpression expr, PositionInfo pos) {
|
||||
DSLWriter::ReportErrors(pos);
|
||||
ThreadContext::ReportErrors(pos);
|
||||
if (expr.valid()) {
|
||||
fExpression = std::move(expr.fExpression);
|
||||
} else {
|
||||
fExpression = SkSL::Poison::Make(pos.line(), DSLWriter::Context());
|
||||
fExpression = SkSL::Poison::Make(pos.line(), ThreadContext::Context());
|
||||
}
|
||||
}
|
||||
|
||||
DSLExpression DSLExpression::Poison(PositionInfo pos) {
|
||||
return DSLExpression(SkSL::Poison::Make(pos.line(), DSLWriter::Context()));
|
||||
return DSLExpression(SkSL::Poison::Make(pos.line(), ThreadContext::Context()));
|
||||
}
|
||||
|
||||
DSLExpression::~DSLExpression() {
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
if (fExpression && DSLWriter::InFragmentProcessor()) {
|
||||
DSLWriter::CurrentEmitArgs()->fFragBuilder->codeAppend(
|
||||
if (fExpression && ThreadContext::InFragmentProcessor()) {
|
||||
ThreadContext::CurrentEmitArgs()->fFragBuilder->codeAppend(
|
||||
DSLStatement(this->release()).release());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
SkASSERTF(!fExpression || !DSLWriter::Settings().fAssertDSLObjectsReleased,
|
||||
SkASSERTF(!fExpression || !ThreadContext::Settings().fAssertDSLObjectsReleased,
|
||||
"Expression destroyed without being incorporated into program (see "
|
||||
"ProgramSettings::fAssertDSLObjectsReleased)");
|
||||
}
|
||||
@ -165,17 +166,17 @@ DSLExpression DSLExpression::a(PositionInfo pos) {
|
||||
}
|
||||
|
||||
DSLExpression DSLExpression::field(skstd::string_view name, PositionInfo pos) {
|
||||
return DSLExpression(FieldAccess::Convert(DSLWriter::Context(), *DSLWriter::SymbolTable(),
|
||||
this->release(), name), pos);
|
||||
return DSLExpression(FieldAccess::Convert(ThreadContext::Context(),
|
||||
*ThreadContext::SymbolTable(), this->release(), name), pos);
|
||||
}
|
||||
|
||||
DSLPossibleExpression DSLExpression::operator=(DSLExpression right) {
|
||||
return BinaryExpression::Convert(DSLWriter::Context(), this->release(),
|
||||
return BinaryExpression::Convert(ThreadContext::Context(), this->release(),
|
||||
SkSL::Token::Kind::TK_EQ, right.release());
|
||||
}
|
||||
|
||||
DSLPossibleExpression DSLExpression::operator[](DSLExpression right) {
|
||||
return IndexExpression::Convert(DSLWriter::Context(), *DSLWriter::SymbolTable(),
|
||||
return IndexExpression::Convert(ThreadContext::Context(), *ThreadContext::SymbolTable(),
|
||||
this->release(), right.release());
|
||||
}
|
||||
|
||||
@ -190,25 +191,25 @@ DSLPossibleExpression DSLExpression::operator()(SkTArray<DSLWrapper<DSLExpressio
|
||||
}
|
||||
|
||||
DSLPossibleExpression DSLExpression::operator()(ExpressionArray args, PositionInfo pos) {
|
||||
return SkSL::FunctionCall::Convert(DSLWriter::Context(), pos.line(), this->release(),
|
||||
return SkSL::FunctionCall::Convert(ThreadContext::Context(), pos.line(), this->release(),
|
||||
std::move(args));
|
||||
}
|
||||
|
||||
#define OP(op, token) \
|
||||
DSLPossibleExpression operator op(DSLExpression left, DSLExpression right) { \
|
||||
return BinaryExpression::Convert(DSLWriter::Context(), left.release(), \
|
||||
return BinaryExpression::Convert(ThreadContext::Context(), left.release(), \
|
||||
SkSL::Token::Kind::token, right.release()); \
|
||||
}
|
||||
|
||||
#define PREFIXOP(op, token) \
|
||||
DSLPossibleExpression operator op(DSLExpression expr) { \
|
||||
return PrefixExpression::Convert(DSLWriter::Context(), SkSL::Token::Kind::token, \
|
||||
return PrefixExpression::Convert(ThreadContext::Context(), SkSL::Token::Kind::token, \
|
||||
expr.release()); \
|
||||
}
|
||||
|
||||
#define POSTFIXOP(op, token) \
|
||||
DSLPossibleExpression operator op(DSLExpression expr, int) { \
|
||||
return PostfixExpression::Convert(DSLWriter::Context(), expr.release(), \
|
||||
return PostfixExpression::Convert(ThreadContext::Context(), expr.release(), \
|
||||
SkSL::Token::Kind::token); \
|
||||
}
|
||||
|
||||
@ -235,7 +236,7 @@ OP(|=, TK_BITWISEOREQ)
|
||||
OP(^, TK_BITWISEXOR)
|
||||
OP(^=, TK_BITWISEXOREQ)
|
||||
DSLPossibleExpression LogicalXor(DSLExpression left, DSLExpression right) {
|
||||
return BinaryExpression::Convert(DSLWriter::Context(), left.release(),
|
||||
return BinaryExpression::Convert(ThreadContext::Context(), left.release(),
|
||||
SkSL::Token::Kind::TK_LOGICALXOR, right.release());
|
||||
}
|
||||
OP(==, TK_EQEQ)
|
||||
@ -255,23 +256,24 @@ PREFIXOP(--, TK_MINUSMINUS)
|
||||
POSTFIXOP(--, TK_MINUSMINUS)
|
||||
|
||||
DSLPossibleExpression operator,(DSLExpression left, DSLExpression right) {
|
||||
return BinaryExpression::Convert(DSLWriter::Context(), left.release(),
|
||||
return BinaryExpression::Convert(ThreadContext::Context(), left.release(),
|
||||
SkSL::Token::Kind::TK_COMMA, right.release());
|
||||
}
|
||||
|
||||
DSLPossibleExpression operator,(DSLPossibleExpression left, DSLExpression right) {
|
||||
return BinaryExpression::Convert(DSLWriter::Context(), DSLExpression(std::move(left)).release(),
|
||||
SkSL::Token::Kind::TK_COMMA, right.release());
|
||||
return BinaryExpression::Convert(ThreadContext::Context(),
|
||||
DSLExpression(std::move(left)).release(), SkSL::Token::Kind::TK_COMMA, right.release());
|
||||
}
|
||||
|
||||
DSLPossibleExpression operator,(DSLExpression left, DSLPossibleExpression right) {
|
||||
return BinaryExpression::Convert(DSLWriter::Context(), left.release(),
|
||||
return BinaryExpression::Convert(ThreadContext::Context(), left.release(),
|
||||
SkSL::Token::Kind::TK_COMMA, DSLExpression(std::move(right)).release());
|
||||
}
|
||||
|
||||
DSLPossibleExpression operator,(DSLPossibleExpression left, DSLPossibleExpression right) {
|
||||
return BinaryExpression::Convert(DSLWriter::Context(), DSLExpression(std::move(left)).release(),
|
||||
SkSL::Token::Kind::TK_COMMA, DSLExpression(std::move(right)).release());
|
||||
return BinaryExpression::Convert(ThreadContext::Context(),
|
||||
DSLExpression(std::move(left)).release(), SkSL::Token::Kind::TK_COMMA,
|
||||
DSLExpression(std::move(right)).release());
|
||||
}
|
||||
|
||||
DSLPossibleExpression::DSLPossibleExpression(std::unique_ptr<SkSL::Expression> expr)
|
||||
@ -289,7 +291,7 @@ DSLPossibleExpression::~DSLPossibleExpression() {
|
||||
|
||||
void DSLPossibleExpression::reportErrors(PositionInfo pos) {
|
||||
SkASSERT(!this->valid());
|
||||
DSLWriter::ReportErrors(pos);
|
||||
ThreadContext::ReportErrors(pos);
|
||||
}
|
||||
|
||||
DSLType DSLPossibleExpression::type() {
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "src/sksl/SkSLAnalysis.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLIRGenerator.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/ir/SkSLFunctionCall.h"
|
||||
#include "src/sksl/ir/SkSLFunctionPrototype.h"
|
||||
@ -24,11 +25,11 @@ void DSLFunction::init(DSLModifiers modifiers, const DSLType& returnType, skstd:
|
||||
SkTArray<DSLParameter*> params, PositionInfo pos) {
|
||||
fPosition = pos;
|
||||
// Conservatively assume all user-defined functions have side effects.
|
||||
if (!DSLWriter::IsModule()) {
|
||||
if (!ThreadContext::IsModule()) {
|
||||
modifiers.fModifiers.fFlags |= Modifiers::kHasSideEffects_Flag;
|
||||
}
|
||||
|
||||
if (DSLWriter::Settings().fForceNoInline) {
|
||||
if (ThreadContext::Settings().fForceNoInline) {
|
||||
// Apply the `noinline` modifier to every function. This allows us to test Runtime
|
||||
// Effects without any inlining, even when the code is later added to a paint.
|
||||
modifiers.fModifiers.fFlags &= ~Modifiers::kInline_Flag;
|
||||
@ -39,7 +40,7 @@ void DSLFunction::init(DSLModifiers modifiers, const DSLType& returnType, skstd:
|
||||
paramVars.reserve(params.size());
|
||||
for (DSLParameter* param : params) {
|
||||
if (param->fDeclared) {
|
||||
DSLWriter::ReportError("parameter has already been used in another function");
|
||||
ThreadContext::ReportError("parameter has already been used in another function");
|
||||
}
|
||||
SkASSERT(!param->fInitialValue.hasValue());
|
||||
SkASSERT(!param->fDeclaration);
|
||||
@ -51,13 +52,13 @@ void DSLFunction::init(DSLModifiers modifiers, const DSLType& returnType, skstd:
|
||||
paramVars.push_back(std::move(paramVar));
|
||||
}
|
||||
SkASSERT(paramVars.size() == params.size());
|
||||
fDecl = SkSL::FunctionDeclaration::Convert(DSLWriter::Context(),
|
||||
*DSLWriter::SymbolTable(),
|
||||
fDecl = SkSL::FunctionDeclaration::Convert(ThreadContext::Context(),
|
||||
*ThreadContext::SymbolTable(),
|
||||
pos.line(),
|
||||
DSLWriter::Modifiers(modifiers.fModifiers),
|
||||
ThreadContext::Modifiers(modifiers.fModifiers),
|
||||
name == "main" ? name : DSLWriter::Name(name),
|
||||
std::move(paramVars), &returnType.skslType());
|
||||
DSLWriter::ReportErrors(pos);
|
||||
ThreadContext::ReportErrors(pos);
|
||||
if (fDecl) {
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
params[i]->fVar = fDecl->parameters()[i];
|
||||
@ -66,8 +67,8 @@ void DSLFunction::init(DSLModifiers modifiers, const DSLType& returnType, skstd:
|
||||
// We don't know when this function is going to be defined; go ahead and add a prototype in
|
||||
// case the definition is delayed. If we end up defining the function immediately, we'll
|
||||
// remove the prototype in define().
|
||||
DSLWriter::ProgramElements().push_back(std::make_unique<SkSL::FunctionPrototype>(
|
||||
pos.line(), fDecl, DSLWriter::IsModule()));
|
||||
ThreadContext::ProgramElements().push_back(std::make_unique<SkSL::FunctionPrototype>(
|
||||
pos.line(), fDecl, ThreadContext::IsModule()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,33 +79,34 @@ void DSLFunction::define(DSLBlock block, PositionInfo pos) {
|
||||
// Release the block so we don't fail its destructor assert.
|
||||
return;
|
||||
}
|
||||
if (!DSLWriter::ProgramElements().empty()) {
|
||||
if (!ThreadContext::ProgramElements().empty()) {
|
||||
// If the last ProgramElement was the prototype for this function, it was unnecessary and we
|
||||
// can remove it.
|
||||
const SkSL::ProgramElement& last = *DSLWriter::ProgramElements().back();
|
||||
const SkSL::ProgramElement& last = *ThreadContext::ProgramElements().back();
|
||||
if (last.is<SkSL::FunctionPrototype>()) {
|
||||
const SkSL::FunctionPrototype& prototype = last.as<SkSL::FunctionPrototype>();
|
||||
if (&prototype.declaration() == fDecl) {
|
||||
DSLWriter::ProgramElements().pop_back();
|
||||
ThreadContext::ProgramElements().pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fDecl->definition()) {
|
||||
DSLWriter::ReportError(String::printf("function '%s' was already defined",
|
||||
ThreadContext::ReportError(String::printf("function '%s' was already defined",
|
||||
fDecl->description().c_str()), pos);
|
||||
block.release();
|
||||
return;
|
||||
}
|
||||
// Append sk_Position fixup to the bottom of main() if this is a vertex program.
|
||||
DSLWriter::IRGenerator().appendRTAdjustFixupToVertexMain(*fDecl, body.get());
|
||||
std::unique_ptr<FunctionDefinition> function = FunctionDefinition::Convert(DSLWriter::Context(),
|
||||
pos.line(),
|
||||
*fDecl,
|
||||
std::move(body),
|
||||
/*builtin=*/false);
|
||||
DSLWriter::ReportErrors(fPosition);
|
||||
ThreadContext::IRGenerator().appendRTAdjustFixupToVertexMain(*fDecl, body.get());
|
||||
std::unique_ptr<FunctionDefinition> function = FunctionDefinition::Convert(
|
||||
ThreadContext::Context(),
|
||||
pos.line(),
|
||||
*fDecl,
|
||||
std::move(body),
|
||||
/*builtin=*/false);
|
||||
ThreadContext::ReportErrors(fPosition);
|
||||
fDecl->setDefinition(function.get());
|
||||
DSLWriter::ProgramElements().push_back(std::move(function));
|
||||
ThreadContext::ProgramElements().push_back(std::move(function));
|
||||
}
|
||||
|
||||
DSLExpression DSLFunction::call(SkTArray<DSLWrapper<DSLExpression>> args, PositionInfo pos) {
|
||||
@ -117,7 +119,7 @@ DSLExpression DSLFunction::call(SkTArray<DSLWrapper<DSLExpression>> args, Positi
|
||||
}
|
||||
|
||||
DSLExpression DSLFunction::call(ExpressionArray args, PositionInfo pos) {
|
||||
std::unique_ptr<SkSL::Expression> result = SkSL::FunctionCall::Convert(DSLWriter::Context(),
|
||||
std::unique_ptr<SkSL::Expression> result = SkSL::FunctionCall::Convert(ThreadContext::Context(),
|
||||
pos.line(), *fDecl, std::move(args));
|
||||
return DSLExpression(std::move(result), pos);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "include/sksl/DSLLayout.h"
|
||||
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
@ -15,7 +15,7 @@ namespace dsl {
|
||||
|
||||
DSLLayout& DSLLayout::flag(SkSL::Layout::Flag mask, const char* name, PositionInfo pos) {
|
||||
if (fSkSLLayout.fFlags & mask) {
|
||||
DSLWriter::ReportError("layout qualifier '" + String(name) + "' appears more than once",
|
||||
ThreadContext::ReportError("layout qualifier '" + String(name) + "' appears more than once",
|
||||
pos);
|
||||
}
|
||||
fSkSLLayout.fFlags |= mask;
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "include/sksl/DSLCore.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLIRGenerator.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
@ -21,7 +21,7 @@ namespace dsl {
|
||||
|
||||
void StartRuntimeShader(SkSL::Compiler* compiler) {
|
||||
Start(compiler, SkSL::ProgramKind::kRuntimeShader);
|
||||
SkSL::ProgramSettings& settings = DSLWriter::Settings();
|
||||
SkSL::ProgramSettings& settings = ThreadContext::Settings();
|
||||
SkASSERT(settings.fInlineThreshold == SkSL::kDefaultInlineThreshold);
|
||||
settings.fInlineThreshold = 0;
|
||||
SkASSERT(!settings.fAllowNarrowingConversions);
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "include/sksl/DSLBlock.h"
|
||||
#include "include/sksl/DSLExpression.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/ir/SkSLBlock.h"
|
||||
#include "src/sksl/ir/SkSLExpressionStatement.h"
|
||||
#include "src/sksl/ir/SkSLNop.h"
|
||||
@ -31,12 +31,12 @@ DSLStatement::DSLStatement(DSLBlock block)
|
||||
DSLStatement::DSLStatement(DSLExpression expr) {
|
||||
std::unique_ptr<SkSL::Expression> skslExpr = expr.release();
|
||||
if (skslExpr) {
|
||||
fStatement = SkSL::ExpressionStatement::Make(DSLWriter::Context(), std::move(skslExpr));
|
||||
fStatement = SkSL::ExpressionStatement::Make(ThreadContext::Context(), std::move(skslExpr));
|
||||
}
|
||||
}
|
||||
|
||||
DSLStatement::DSLStatement(std::unique_ptr<SkSL::Expression> expr)
|
||||
: fStatement(SkSL::ExpressionStatement::Make(DSLWriter::Context(), std::move(expr))) {
|
||||
: fStatement(SkSL::ExpressionStatement::Make(ThreadContext::Context(), std::move(expr))) {
|
||||
SkASSERT(this->hasValue());
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ DSLStatement::DSLStatement(DSLPossibleExpression expr, PositionInfo pos)
|
||||
: DSLStatement(DSLExpression(std::move(expr), pos)) {}
|
||||
|
||||
DSLStatement::DSLStatement(DSLPossibleStatement stmt, PositionInfo pos) {
|
||||
DSLWriter::ReportErrors(pos);
|
||||
ThreadContext::ReportErrors(pos);
|
||||
if (stmt.hasValue()) {
|
||||
fStatement = std::move(stmt.fStatement);
|
||||
} else {
|
||||
@ -62,12 +62,12 @@ DSLStatement::DSLStatement(DSLPossibleStatement stmt, PositionInfo pos) {
|
||||
|
||||
DSLStatement::~DSLStatement() {
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
if (fStatement && DSLWriter::InFragmentProcessor()) {
|
||||
DSLWriter::CurrentEmitArgs()->fFragBuilder->codeAppend(this->release());
|
||||
if (fStatement && ThreadContext::InFragmentProcessor()) {
|
||||
ThreadContext::CurrentEmitArgs()->fFragBuilder->codeAppend(this->release());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
SkASSERTF(!fStatement || !DSLWriter::Settings().fAssertDSLObjectsReleased,
|
||||
SkASSERTF(!fStatement || !ThreadContext::Settings().fAssertDSLObjectsReleased,
|
||||
"Statement destroyed without being incorporated into program (see "
|
||||
"ProgramSettings::fAssertDSLObjectsReleased)");
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "include/sksl/DSLSymbols.h"
|
||||
|
||||
#include "src/sksl/SkSLIRGenerator.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
|
||||
namespace SkSL {
|
||||
@ -15,19 +16,19 @@ namespace SkSL {
|
||||
namespace dsl {
|
||||
|
||||
void PushSymbolTable() {
|
||||
SymbolTable::Push(&DSLWriter::IRGenerator().symbolTable());
|
||||
SymbolTable::Push(&ThreadContext::IRGenerator().symbolTable());
|
||||
}
|
||||
|
||||
void PopSymbolTable() {
|
||||
SymbolTable::Pop(&DSLWriter::IRGenerator().symbolTable());
|
||||
SymbolTable::Pop(&ThreadContext::IRGenerator().symbolTable());
|
||||
}
|
||||
|
||||
std::shared_ptr<SymbolTable> CurrentSymbolTable() {
|
||||
return DSLWriter::IRGenerator().symbolTable();
|
||||
return ThreadContext::IRGenerator().symbolTable();
|
||||
}
|
||||
|
||||
DSLPossibleExpression Symbol(skstd::string_view name, PositionInfo pos) {
|
||||
return DSLWriter::IRGenerator().convertIdentifier(pos.line(), name);
|
||||
return ThreadContext::IRGenerator().convertIdentifier(pos.line(), name);
|
||||
}
|
||||
|
||||
bool IsType(skstd::string_view name) {
|
||||
@ -40,7 +41,7 @@ void AddToSymbolTable(DSLVarBase& var, PositionInfo pos) {
|
||||
if (skslVar) {
|
||||
CurrentSymbolTable()->addWithoutOwnership(skslVar);
|
||||
}
|
||||
DSLWriter::ReportErrors(pos);
|
||||
ThreadContext::ReportErrors(pos);
|
||||
}
|
||||
|
||||
const String* Retain(String string) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "include/sksl/DSLType.h"
|
||||
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/ir/SkSLConstructor.h"
|
||||
#include "src/sksl/ir/SkSLStructDefinition.h"
|
||||
|
||||
@ -35,7 +35,7 @@ static const SkSL::Type* verify_type(const Context& context,
|
||||
static const SkSL::Type* find_type(const Context& context,
|
||||
skstd::string_view name,
|
||||
PositionInfo pos) {
|
||||
const Symbol* symbol = (*DSLWriter::SymbolTable())[name];
|
||||
const Symbol* symbol = (*ThreadContext::SymbolTable())[name];
|
||||
if (!symbol) {
|
||||
context.fErrors->error(String::printf("no symbol named '%.*s'",
|
||||
(int)name.length(), name.data()), pos);
|
||||
@ -55,9 +55,9 @@ static const SkSL::Type* find_type(const Context& context,
|
||||
Modifiers* modifiers,
|
||||
PositionInfo pos) {
|
||||
const Type* type = find_type(context, name, pos);
|
||||
type = type->applyPrecisionQualifiers(context, modifiers, DSLWriter::SymbolTable().get(),
|
||||
type = type->applyPrecisionQualifiers(context, modifiers, ThreadContext::SymbolTable().get(),
|
||||
pos.line());
|
||||
DSLWriter::ReportErrors(pos);
|
||||
ThreadContext::ReportErrors(pos);
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -167,13 +167,13 @@ static const SkSL::Type* get_type_from_type_constant(const Context& context, Typ
|
||||
}
|
||||
|
||||
DSLType::DSLType(skstd::string_view name)
|
||||
: fSkSLType(find_type(DSLWriter::Context(), name, PositionInfo())) {}
|
||||
: fSkSLType(find_type(ThreadContext::Context(), name, PositionInfo())) {}
|
||||
|
||||
DSLType::DSLType(skstd::string_view name, DSLModifiers* modifiers, PositionInfo position)
|
||||
: fSkSLType(find_type(DSLWriter::Context(), name, &modifiers->fModifiers, position)) {}
|
||||
: fSkSLType(find_type(ThreadContext::Context(), name, &modifiers->fModifiers, position)) {}
|
||||
|
||||
DSLType::DSLType(const SkSL::Type* type)
|
||||
: fSkSLType(verify_type(DSLWriter::Context(), type, /*allowPrivateTypes=*/true,
|
||||
: fSkSLType(verify_type(ThreadContext::Context(), type, /*allowPrivateTypes=*/true,
|
||||
PositionInfo())) {}
|
||||
|
||||
bool DSLType::isBoolean() const {
|
||||
@ -228,7 +228,7 @@ const SkSL::Type& DSLType::skslType() const {
|
||||
if (fSkSLType) {
|
||||
return *fSkSLType;
|
||||
}
|
||||
const Context& context = DSLWriter::Context();
|
||||
const Context& context = ThreadContext::Context();
|
||||
return *verify_type(context,
|
||||
get_type_from_type_constant(context, fTypeConstant),
|
||||
/*allowPrivateTypes=*/true,
|
||||
@ -245,18 +245,18 @@ DSLPossibleExpression DSLType::Construct(DSLType type, SkSpan<DSLExpression> arg
|
||||
}
|
||||
skslArgs.push_back(arg.release());
|
||||
}
|
||||
return SkSL::Constructor::Convert(DSLWriter::Context(), /*line=*/-1, type.skslType(),
|
||||
return SkSL::Constructor::Convert(ThreadContext::Context(), /*line=*/-1, type.skslType(),
|
||||
std::move(skslArgs));
|
||||
}
|
||||
|
||||
DSLType Array(const DSLType& base, int count, PositionInfo pos) {
|
||||
count = base.skslType().convertArraySize(DSLWriter::Context(),
|
||||
count = base.skslType().convertArraySize(ThreadContext::Context(),
|
||||
DSLExpression(count, pos).release());
|
||||
DSLWriter::ReportErrors(pos);
|
||||
ThreadContext::ReportErrors(pos);
|
||||
if (!count) {
|
||||
return DSLType(kPoison_Type);
|
||||
}
|
||||
return DSLWriter::SymbolTable()->addArrayDimension(&base.skslType(), count);
|
||||
return ThreadContext::SymbolTable()->addArrayDimension(&base.skslType(), count);
|
||||
}
|
||||
|
||||
DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields, PositionInfo pos) {
|
||||
@ -266,25 +266,24 @@ DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields, PositionInfo po
|
||||
if (field.fModifiers.fModifiers.fFlags != Modifiers::kNo_Flag) {
|
||||
String desc = field.fModifiers.fModifiers.description();
|
||||
desc.pop_back(); // remove trailing space
|
||||
DSLWriter::ReportError("modifier '" + desc + "' is not permitted on a struct field",
|
||||
ThreadContext::ReportError("modifier '" + desc + "' is not permitted on a struct field",
|
||||
field.fPosition);
|
||||
}
|
||||
|
||||
const SkSL::Type& type = field.fType.skslType();
|
||||
if (type.isOpaque()) {
|
||||
DSLWriter::ReportError("opaque type '" + type.displayName() +
|
||||
ThreadContext::ReportError("opaque type '" + type.displayName() +
|
||||
"' is not permitted in a struct", field.fPosition);
|
||||
}
|
||||
skslFields.emplace_back(field.fModifiers.fModifiers, field.fName, &type);
|
||||
}
|
||||
const SkSL::Type* result = DSLWriter::SymbolTable()->add(Type::MakeStructType(pos.line(),
|
||||
name,
|
||||
skslFields));
|
||||
const SkSL::Type* result = ThreadContext::SymbolTable()->add(Type::MakeStructType(pos.line(),
|
||||
name, skslFields));
|
||||
if (result->isTooDeeplyNested()) {
|
||||
DSLWriter::ReportError("struct '" + String(name) + "' is too deeply nested", pos);
|
||||
ThreadContext::ReportError("struct '" + String(name) + "' is too deeply nested", pos);
|
||||
}
|
||||
DSLWriter::ProgramElements().push_back(std::make_unique<SkSL::StructDefinition>(/*line=*/-1,
|
||||
*result));
|
||||
ThreadContext::ProgramElements().push_back(std::make_unique<SkSL::StructDefinition>(/*line=*/-1,
|
||||
*result));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "include/sksl/DSLModifiers.h"
|
||||
#include "include/sksl/DSLType.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/SkSLUtil.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/ir/SkSLBinaryExpression.h"
|
||||
@ -44,30 +45,25 @@ DSLVarBase::DSLVarBase(const DSLModifiers& modifiers, DSLType type, skstd::strin
|
||||
, fPosition(pos) {
|
||||
if (fModifiers.fModifiers.fFlags & Modifiers::kUniform_Flag) {
|
||||
#if SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
|
||||
if (DSLWriter::InFragmentProcessor()) {
|
||||
if (ThreadContext::InFragmentProcessor()) {
|
||||
const SkSL::Type& skslType = type.skslType();
|
||||
GrSLType grslType;
|
||||
int count;
|
||||
if (skslType.isArray()) {
|
||||
SkAssertResult(SkSL::type_to_grsltype(DSLWriter::Context(),
|
||||
skslType.componentType(),
|
||||
&grslType));
|
||||
SkAssertResult(SkSL::type_to_grsltype(ThreadContext::Context(),
|
||||
skslType.componentType(), &grslType));
|
||||
count = skslType.columns();
|
||||
SkASSERT(count > 0);
|
||||
} else {
|
||||
SkAssertResult(SkSL::type_to_grsltype(DSLWriter::Context(), skslType,
|
||||
&grslType));
|
||||
SkAssertResult(SkSL::type_to_grsltype(ThreadContext::Context(), skslType,
|
||||
&grslType));
|
||||
count = 0;
|
||||
}
|
||||
const char* uniformName;
|
||||
SkASSERT(DSLWriter::CurrentEmitArgs());
|
||||
fUniformHandle = DSLWriter::CurrentEmitArgs()->fUniformHandler->addUniformArray(
|
||||
&DSLWriter::CurrentEmitArgs()->fFp,
|
||||
kFragment_GrShaderFlag,
|
||||
grslType,
|
||||
String(this->name()).c_str(),
|
||||
count,
|
||||
&uniformName).toIndex();
|
||||
SkASSERT(ThreadContext::CurrentEmitArgs());
|
||||
fUniformHandle = ThreadContext::CurrentEmitArgs()->fUniformHandler->addUniformArray(
|
||||
&ThreadContext::CurrentEmitArgs()->fFp, kFragment_GrShaderFlag, grslType,
|
||||
String(this->name()).c_str(), count, &uniformName).toIndex();
|
||||
fName = uniformName;
|
||||
}
|
||||
#endif // SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
|
||||
@ -76,10 +72,10 @@ DSLVarBase::DSLVarBase(const DSLModifiers& modifiers, DSLType type, skstd::strin
|
||||
|
||||
DSLVarBase::~DSLVarBase() {
|
||||
if (fDeclaration && !fDeclared) {
|
||||
DSLWriter::ReportError(String::printf("variable '%.*s' was destroyed without being "
|
||||
"declared",
|
||||
(int)fRawName.length(),
|
||||
fRawName.data()).c_str());
|
||||
ThreadContext::ReportError(String::printf("variable '%.*s' was destroyed without being "
|
||||
"declared",
|
||||
(int)fRawName.length(),
|
||||
fRawName.data()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,30 +108,30 @@ DSLGlobalVar::DSLGlobalVar(const char* name)
|
||||
DSLWriter::MarkDeclared(*this);
|
||||
#if SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
|
||||
if (!strcmp(name, "sk_SampleCoord")) {
|
||||
fName = DSLWriter::CurrentEmitArgs()->fSampleCoord;
|
||||
fName = ThreadContext::CurrentEmitArgs()->fSampleCoord;
|
||||
// The actual sk_SampleCoord variable hasn't been created by GrGLSLFPFragmentBuilder yet, so
|
||||
// if we attempt to look it up in the symbol table we'll get null. As we are currently
|
||||
// converting all DSL code into strings rather than nodes, all we really need is a
|
||||
// correctly-named variable with the right type, so we just create a placeholder for it.
|
||||
// TODO(skia/11330): we'll need to fix this when switching over to nodes.
|
||||
const SkSL::Modifiers* modifiers = DSLWriter::Context().fModifiersPool->add(
|
||||
const SkSL::Modifiers* modifiers = ThreadContext::Context().fModifiersPool->add(
|
||||
SkSL::Modifiers(SkSL::Layout(/*flags=*/0, /*location=*/-1, /*offset=*/-1,
|
||||
/*binding=*/-1, /*index=*/-1, /*set=*/-1,
|
||||
SK_MAIN_COORDS_BUILTIN, /*inputAttachmentIndex=*/-1),
|
||||
SkSL::Modifiers::kNo_Flag));
|
||||
|
||||
fVar = DSLWriter::SymbolTable()->takeOwnershipOfIRNode(std::make_unique<SkSL::Variable>(
|
||||
fVar = ThreadContext::SymbolTable()->takeOwnershipOfIRNode(std::make_unique<SkSL::Variable>(
|
||||
/*line=*/-1,
|
||||
modifiers,
|
||||
fName,
|
||||
DSLWriter::Context().fTypes.fFloat2.get(),
|
||||
ThreadContext::Context().fTypes.fFloat2.get(),
|
||||
/*builtin=*/true,
|
||||
SkSL::VariableStorage::kGlobal));
|
||||
fInitialized = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const SkSL::Symbol* result = (*DSLWriter::SymbolTable())[fName];
|
||||
const SkSL::Symbol* result = (*ThreadContext::SymbolTable())[fName];
|
||||
SkASSERTF(result, "could not find '%.*s' in symbol table", (int)fName.length(), fName.data());
|
||||
fVar = &result->as<SkSL::Variable>();
|
||||
fInitialized = true;
|
||||
@ -163,7 +159,7 @@ DSLPossibleExpression DSLVarBase::operator[](DSLExpression&& index) {
|
||||
}
|
||||
|
||||
DSLPossibleExpression DSLVarBase::assign(DSLExpression expr) {
|
||||
return BinaryExpression::Convert(DSLWriter::Context(),
|
||||
return BinaryExpression::Convert(ThreadContext::Context(),
|
||||
DSLExpression(*this, PositionInfo()).release(), SkSL::Token::Kind::TK_EQ,
|
||||
expr.release());
|
||||
}
|
||||
@ -183,17 +179,17 @@ DSLPossibleExpression DSLParameter::operator=(DSLExpression expr) {
|
||||
std::unique_ptr<SkSL::Expression> DSLGlobalVar::methodCall(skstd::string_view methodName,
|
||||
PositionInfo pos) {
|
||||
if (!this->fType.isEffectChild()) {
|
||||
DSLWriter::ReportError("type does not support method calls", pos);
|
||||
ThreadContext::ReportError("type does not support method calls", pos);
|
||||
return nullptr;
|
||||
}
|
||||
return FieldAccess::Convert(DSLWriter::Context(), *DSLWriter::SymbolTable(),
|
||||
return FieldAccess::Convert(ThreadContext::Context(), *ThreadContext::SymbolTable(),
|
||||
DSLExpression(*this, PositionInfo()).release(), methodName);
|
||||
}
|
||||
|
||||
DSLExpression DSLGlobalVar::eval(ExpressionArray args, PositionInfo pos) {
|
||||
auto method = this->methodCall("eval", pos);
|
||||
return DSLExpression(
|
||||
method ? SkSL::FunctionCall::Convert(DSLWriter::Context(), pos.line(),
|
||||
method ? SkSL::FunctionCall::Convert(ThreadContext::Context(), pos.line(),
|
||||
std::move(method), std::move(args))
|
||||
: nullptr,
|
||||
pos);
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "src/sksl/dsl/priv/DSLFPs.h"
|
||||
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/ir/SkSLCodeStringExpression.h"
|
||||
|
||||
@ -18,11 +19,11 @@ namespace dsl {
|
||||
|
||||
void StartFragmentProcessor(GrFragmentProcessor::ProgramImpl* processor,
|
||||
GrFragmentProcessor::ProgramImpl::EmitArgs* emitArgs) {
|
||||
DSLWriter::StartFragmentProcessor(processor, emitArgs);
|
||||
ThreadContext::StartFragmentProcessor(processor, emitArgs);
|
||||
}
|
||||
|
||||
void EndFragmentProcessor() {
|
||||
DSLWriter::EndFragmentProcessor();
|
||||
ThreadContext::EndFragmentProcessor();
|
||||
}
|
||||
|
||||
DSLGlobalVar sk_SampleCoord() {
|
||||
@ -36,8 +37,8 @@ DSLExpression SampleChild(int index, DSLExpression sampleExpr) {
|
||||
SkASSERT(expr->type().componentType().isFloat());
|
||||
}
|
||||
|
||||
GrFragmentProcessor::ProgramImpl* proc = DSLWriter::CurrentProcessor();
|
||||
GrFragmentProcessor::ProgramImpl::EmitArgs& emitArgs = *DSLWriter::CurrentEmitArgs();
|
||||
GrFragmentProcessor::ProgramImpl* proc = ThreadContext::CurrentProcessor();
|
||||
GrFragmentProcessor::ProgramImpl::EmitArgs& emitArgs = *ThreadContext::CurrentEmitArgs();
|
||||
SkString code;
|
||||
switch (expr ? expr->type().columns() : 0) {
|
||||
default:
|
||||
@ -55,7 +56,7 @@ DSLExpression SampleChild(int index, DSLExpression sampleExpr) {
|
||||
}
|
||||
|
||||
return DSLExpression(std::make_unique<SkSL::CodeStringExpression>(
|
||||
code.c_str(), DSLWriter::Context().fTypes.fHalf4.get()));
|
||||
code.c_str(), ThreadContext::Context().fTypes.fHalf4.get()));
|
||||
}
|
||||
|
||||
GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLGlobalVar& var) {
|
||||
|
@ -7,178 +7,33 @@
|
||||
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
|
||||
#include "include/private/SkSLDefines.h"
|
||||
#include "include/sksl/DSLCore.h"
|
||||
#include "include/sksl/DSLStatement.h"
|
||||
#include "include/sksl/DSLSymbols.h"
|
||||
#include "include/sksl/SkSLErrorReporter.h"
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
#include "src/gpu/mock/GrMockCaps.h"
|
||||
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "include/sksl/DSLVar.h"
|
||||
#include "src/sksl/SkSLIRGenerator.h"
|
||||
#include "src/sksl/SkSLIntrinsicMap.h"
|
||||
#include "src/sksl/ir/SkSLBinaryExpression.h"
|
||||
#include "src/sksl/ir/SkSLBlock.h"
|
||||
#include "src/sksl/ir/SkSLConstructor.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/ir/SkSLNop.h"
|
||||
#include "src/sksl/ir/SkSLPostfixExpression.h"
|
||||
#include "src/sksl/ir/SkSLPrefixExpression.h"
|
||||
#include "src/sksl/ir/SkSLSwitchStatement.h"
|
||||
#include "src/sksl/ir/SkSLVariable.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
namespace dsl {
|
||||
|
||||
DSLWriter::DSLWriter(SkSL::Compiler* compiler, SkSL::ProgramKind kind,
|
||||
const SkSL::ProgramSettings& settings, SkSL::ParsedModule module,
|
||||
bool isModule)
|
||||
: fCompiler(compiler)
|
||||
, fOldErrorReporter(*fCompiler->fContext->fErrors)
|
||||
, fSettings(settings) {
|
||||
fOldModifiersPool = fCompiler->fContext->fModifiersPool;
|
||||
|
||||
fOldConfig = fCompiler->fContext->fConfig;
|
||||
|
||||
if (!isModule) {
|
||||
if (compiler->context().fCaps.useNodePools() && settings.fDSLUseMemoryPool) {
|
||||
fPool = Pool::Create();
|
||||
fPool->attachToThread();
|
||||
}
|
||||
fModifiersPool = std::make_unique<SkSL::ModifiersPool>();
|
||||
fCompiler->fContext->fModifiersPool = fModifiersPool.get();
|
||||
}
|
||||
|
||||
fConfig = std::make_unique<SkSL::ProgramConfig>();
|
||||
fConfig->fKind = kind;
|
||||
fConfig->fSettings = settings;
|
||||
fConfig->fIsBuiltinCode = isModule;
|
||||
fCompiler->fContext->fConfig = fConfig.get();
|
||||
fCompiler->fContext->fErrors = &fDefaultErrorReporter;
|
||||
fCompiler->fContext->fIntrinsics = module.fIntrinsics.get();
|
||||
if (fCompiler->fContext->fIntrinsics) {
|
||||
fCompiler->fContext->fIntrinsics->resetAlreadyIncluded();
|
||||
}
|
||||
|
||||
fCompiler->fIRGenerator->start(module, &fProgramElements, &fSharedElements);
|
||||
}
|
||||
|
||||
DSLWriter::~DSLWriter() {
|
||||
if (SymbolTable()) {
|
||||
fCompiler->fIRGenerator->finish();
|
||||
fProgramElements.clear();
|
||||
} else {
|
||||
// We should only be here with a null symbol table if ReleaseProgram was called
|
||||
SkASSERT(fProgramElements.empty());
|
||||
}
|
||||
fCompiler->fContext->fErrors = &fOldErrorReporter;
|
||||
fCompiler->fContext->fConfig = fOldConfig;
|
||||
fCompiler->fContext->fModifiersPool = fOldModifiersPool;
|
||||
if (fPool) {
|
||||
fPool->detachFromThread();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SkSL::IRGenerator& DSLWriter::IRGenerator() {
|
||||
return *Compiler().fIRGenerator;
|
||||
}
|
||||
|
||||
SkSL::Context& DSLWriter::Context() {
|
||||
return Compiler().context();
|
||||
}
|
||||
|
||||
SkSL::ProgramSettings& DSLWriter::Settings() {
|
||||
return Context().fConfig->fSettings;
|
||||
}
|
||||
|
||||
SkSL::Program::Inputs& DSLWriter::Inputs() {
|
||||
return IRGenerator().fInputs;
|
||||
}
|
||||
|
||||
const std::shared_ptr<SkSL::SymbolTable>& DSLWriter::SymbolTable() {
|
||||
return IRGenerator().fSymbolTable;
|
||||
}
|
||||
|
||||
void DSLWriter::Reset() {
|
||||
dsl::PopSymbolTable();
|
||||
dsl::PushSymbolTable();
|
||||
ProgramElements().clear();
|
||||
GetModifiersPool()->clear();
|
||||
}
|
||||
|
||||
const SkSL::Modifiers* DSLWriter::Modifiers(const SkSL::Modifiers& modifiers) {
|
||||
return Context().fModifiersPool->add(modifiers);
|
||||
bool DSLWriter::ManglingEnabled() {
|
||||
return ThreadContext::Instance().fSettings.fDSLMangling;
|
||||
}
|
||||
|
||||
skstd::string_view DSLWriter::Name(skstd::string_view name) {
|
||||
if (ManglingEnabled()) {
|
||||
const String* s = SymbolTable()->takeOwnershipOfString(
|
||||
Instance().fMangler.uniqueName(name, SymbolTable().get()));
|
||||
const String* s = ThreadContext::SymbolTable()->takeOwnershipOfString(
|
||||
ThreadContext::Instance().fMangler.uniqueName(name,
|
||||
ThreadContext::SymbolTable().get()));
|
||||
return s->c_str();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
void DSLWriter::StartFragmentProcessor(GrFragmentProcessor::ProgramImpl* processor,
|
||||
GrFragmentProcessor::ProgramImpl::EmitArgs* emitArgs) {
|
||||
DSLWriter& instance = Instance();
|
||||
instance.fStack.push({processor, emitArgs, StatementArray{}});
|
||||
CurrentEmitArgs()->fFragBuilder->fDeclarations.swap(instance.fStack.top().fSavedDeclarations);
|
||||
dsl::PushSymbolTable();
|
||||
}
|
||||
|
||||
void DSLWriter::EndFragmentProcessor() {
|
||||
DSLWriter& instance = Instance();
|
||||
SkASSERT(!instance.fStack.empty());
|
||||
CurrentEmitArgs()->fFragBuilder->fDeclarations.swap(instance.fStack.top().fSavedDeclarations);
|
||||
instance.fStack.pop();
|
||||
dsl::PopSymbolTable();
|
||||
}
|
||||
|
||||
GrGLSLUniformHandler::UniformHandle DSLWriter::VarUniformHandle(const DSLGlobalVar& var) {
|
||||
return GrGLSLUniformHandler::UniformHandle(var.fUniformHandle);
|
||||
}
|
||||
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
|
||||
void DSLWriter::AddVarDeclaration(DSLStatement& existing, DSLVar& additional) {
|
||||
if (existing.fStatement->is<Block>()) {
|
||||
SkSL::Block& block = existing.fStatement->as<Block>();
|
||||
SkASSERT(!block.isScope());
|
||||
block.children().push_back(Declare(additional).release());
|
||||
} else if (existing.fStatement->is<VarDeclaration>()) {
|
||||
StatementArray stmts;
|
||||
stmts.reserve_back(2);
|
||||
stmts.push_back(std::move(existing.fStatement));
|
||||
stmts.push_back(Declare(additional).release());
|
||||
existing.fStatement = SkSL::Block::MakeUnscoped(/*line=*/-1, std::move(stmts));
|
||||
} else if (existing.fStatement->isEmpty()) {
|
||||
// If the variable declaration generated an error, we can end up with a Nop statement here.
|
||||
existing.fStatement = Declare(additional).release();
|
||||
}
|
||||
}
|
||||
|
||||
void DSLWriter::SetErrorReporter(ErrorReporter* errorReporter) {
|
||||
SkASSERT(errorReporter);
|
||||
Context().fErrors = errorReporter;
|
||||
}
|
||||
|
||||
void DSLWriter::ReportError(skstd::string_view msg, PositionInfo info) {
|
||||
GetErrorReporter().error(msg, info);
|
||||
}
|
||||
|
||||
void DSLWriter::DefaultErrorReporter::handleError(skstd::string_view msg, PositionInfo pos) {
|
||||
if (pos.line() > -1) {
|
||||
SK_ABORT("error: %s: %d: %.*sNo SkSL DSL error reporter configured, treating this as a "
|
||||
"fatal error\n", pos.file_name(), pos.line(), (int)msg.length(), msg.data());
|
||||
} else {
|
||||
SK_ABORT("error: %.*s\nNo SkSL DSL error reporter configured, treating this as a fatal "
|
||||
"error\n", (int)msg.length(), msg.data());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const SkSL::Variable* DSLWriter::Var(DSLVarBase& var) {
|
||||
// fInitialized is true if we have attempted to create a var, whether or not we actually
|
||||
// succeeded. If it's true, we don't want to try again, to avoid reporting the same error
|
||||
@ -192,19 +47,12 @@ const SkSL::Variable* DSLWriter::Var(DSLVarBase& var) {
|
||||
if (baseType->isArray()) {
|
||||
baseType = &baseType->componentType();
|
||||
}
|
||||
DSLWriter::IRGenerator().checkVarDeclaration(var.fPosition.line(),
|
||||
var.fModifiers.fModifiers,
|
||||
baseType,
|
||||
var.storage());
|
||||
ThreadContext::IRGenerator().checkVarDeclaration(var.fPosition.line(),
|
||||
var.fModifiers.fModifiers, baseType, var.storage());
|
||||
}
|
||||
std::unique_ptr<SkSL::Variable> skslvar = DSLWriter::IRGenerator().convertVar(
|
||||
var.fPosition.line(),
|
||||
var.fModifiers.fModifiers,
|
||||
&var.fType.skslType(),
|
||||
var.fName,
|
||||
/*isArray=*/false,
|
||||
/*arraySize=*/nullptr,
|
||||
var.storage());
|
||||
std::unique_ptr<SkSL::Variable> skslvar = ThreadContext::IRGenerator().convertVar(
|
||||
var.fPosition.line(), var.fModifiers.fModifiers, &var.fType.skslType(), var.fName,
|
||||
/*isArray=*/false, /*arraySize=*/nullptr, var.storage());
|
||||
SkSL::Variable* varPtr = skslvar.get();
|
||||
if (var.storage() != SkSL::VariableStorage::kParameter) {
|
||||
// We can't call VarDeclaration::Convert directly here, because the IRGenerator has
|
||||
@ -214,7 +62,7 @@ const SkSL::Variable* DSLWriter::Var(DSLVarBase& var) {
|
||||
// FunctionDeclaration is created which makes this the wrong spot for them, and outside
|
||||
// of DSLParser we don't even need DSL variables to show up in the symbol table in the
|
||||
// first place.
|
||||
var.fDeclaration = DSLWriter::IRGenerator().convertVarDeclaration(
|
||||
var.fDeclaration = ThreadContext::IRGenerator().convertVarDeclaration(
|
||||
std::move(skslvar), var.fInitialValue.releaseIfPossible(),
|
||||
/*addToSymbolTable=*/false);
|
||||
if (var.fDeclaration) {
|
||||
@ -222,7 +70,7 @@ const SkSL::Variable* DSLWriter::Var(DSLVarBase& var) {
|
||||
var.fInitialized = true;
|
||||
}
|
||||
}
|
||||
ReportErrors(var.fPosition);
|
||||
ThreadContext::ReportErrors(var.fPosition);
|
||||
}
|
||||
return var.fVar;
|
||||
}
|
||||
@ -231,9 +79,9 @@ std::unique_ptr<SkSL::Variable> DSLWriter::CreateParameterVar(DSLParameter& var)
|
||||
// This should only be called on undeclared parameter variables, but we allow the creation to go
|
||||
// ahead regardless so we don't have to worry about null pointers potentially sneaking in and
|
||||
// breaking things. DSLFunction is responsible for reporting errors for invalid parameters.
|
||||
return DSLWriter::IRGenerator().convertVar(var.fPosition.line(), var.fModifiers.fModifiers,
|
||||
&var.fType.skslType(), var.fName, /*isArray=*/false,
|
||||
/*arraySize=*/nullptr, var.storage());
|
||||
return ThreadContext::IRGenerator().convertVar(var.fPosition.line(), var.fModifiers.fModifiers,
|
||||
&var.fType.skslType(), var.fName, /*isArray=*/false, /*arraySize=*/nullptr,
|
||||
var.storage());
|
||||
}
|
||||
|
||||
std::unique_ptr<SkSL::Statement> DSLWriter::Declaration(DSLVarBase& var) {
|
||||
@ -252,25 +100,38 @@ void DSLWriter::MarkDeclared(DSLVarBase& var) {
|
||||
var.fDeclared = true;
|
||||
}
|
||||
|
||||
void DSLWriter::ReportErrors(PositionInfo pos) {
|
||||
GetErrorReporter().reportPendingErrors(pos);
|
||||
bool DSLWriter::MarkVarsDeclared() {
|
||||
return ThreadContext::Instance().fSettings.fDSLMarkVarsDeclared;
|
||||
}
|
||||
|
||||
thread_local DSLWriter* instance = nullptr;
|
||||
|
||||
bool DSLWriter::IsActive() {
|
||||
return instance != nullptr;
|
||||
void DSLWriter::AddVarDeclaration(DSLStatement& existing, DSLVar& additional) {
|
||||
if (existing.fStatement->is<Block>()) {
|
||||
SkSL::Block& block = existing.fStatement->as<Block>();
|
||||
SkASSERT(!block.isScope());
|
||||
block.children().push_back(Declare(additional).release());
|
||||
} else if (existing.fStatement->is<VarDeclaration>()) {
|
||||
StatementArray stmts;
|
||||
stmts.reserve_back(2);
|
||||
stmts.push_back(std::move(existing.fStatement));
|
||||
stmts.push_back(Declare(additional).release());
|
||||
existing.fStatement = SkSL::Block::MakeUnscoped(/*line=*/-1, std::move(stmts));
|
||||
} else if (existing.fStatement->isEmpty()) {
|
||||
// If the variable declaration generated an error, we can end up with a Nop statement here.
|
||||
existing.fStatement = Declare(additional).release();
|
||||
}
|
||||
}
|
||||
|
||||
DSLWriter& DSLWriter::Instance() {
|
||||
SkASSERTF(instance, "dsl::Start() has not been called");
|
||||
return *instance;
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
GrGLSLUniformHandler::UniformHandle DSLWriter::VarUniformHandle(const DSLGlobalVar& var) {
|
||||
return GrGLSLUniformHandler::UniformHandle(var.fUniformHandle);
|
||||
}
|
||||
#endif
|
||||
|
||||
void DSLWriter::SetInstance(std::unique_ptr<DSLWriter> newInstance) {
|
||||
SkASSERT((instance == nullptr) != (newInstance == nullptr));
|
||||
delete instance;
|
||||
instance = newInstance.release();
|
||||
void DSLWriter::Reset() {
|
||||
dsl::PopSymbolTable();
|
||||
dsl::PushSymbolTable();
|
||||
ThreadContext::ProgramElements().clear();
|
||||
ThreadContext::GetModifiersPool()->clear();
|
||||
}
|
||||
|
||||
} // namespace dsl
|
||||
|
@ -8,214 +8,33 @@
|
||||
#ifndef SKSL_DSLWRITER
|
||||
#define SKSL_DSLWRITER
|
||||
|
||||
#include "include/core/SkSpan.h"
|
||||
#include "include/core/SkStringView.h"
|
||||
#include "include/private/SkSLModifiers.h"
|
||||
#include "include/private/SkSLStatement.h"
|
||||
#include "include/sksl/DSLExpression.h"
|
||||
#include "include/sksl/DSLStatement.h"
|
||||
#include "src/sksl/SkSLMangler.h"
|
||||
#include "src/sksl/SkSLOperators.h"
|
||||
#include "src/sksl/SkSLParsedModule.h"
|
||||
#include "src/sksl/ir/SkSLExpressionStatement.h"
|
||||
#include "src/sksl/ir/SkSLProgram.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
#include "src/gpu/GrFragmentProcessor.h"
|
||||
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
#include <list>
|
||||
#include <stack>
|
||||
|
||||
class AutoDSLContext;
|
||||
#include <memory>
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
class Compiler;
|
||||
class Context;
|
||||
class IRGenerator;
|
||||
class ProgramElement;
|
||||
class SymbolTable;
|
||||
class Type;
|
||||
class Variable;
|
||||
class Statement;
|
||||
|
||||
namespace dsl {
|
||||
|
||||
class DSLGlobalVar;
|
||||
class DSLParameter;
|
||||
class DSLStatement;
|
||||
class DSLVarBase;
|
||||
class DSLVar;
|
||||
|
||||
/**
|
||||
* Thread-safe class that tracks per-thread state associated with DSL output. This class is for
|
||||
* internal use only.
|
||||
* Various utility methods needed by DSL code.
|
||||
*/
|
||||
class DSLWriter {
|
||||
public:
|
||||
DSLWriter(SkSL::Compiler* compiler, SkSL::ProgramKind kind,
|
||||
const SkSL::ProgramSettings& settings, SkSL::ParsedModule module, bool isModule);
|
||||
|
||||
~DSLWriter();
|
||||
|
||||
/**
|
||||
* Returns true if the DSL has been started.
|
||||
*/
|
||||
static bool IsActive();
|
||||
|
||||
/**
|
||||
* Returns the Compiler used by DSL operations in the current thread.
|
||||
*/
|
||||
static SkSL::Compiler& Compiler() { return *Instance().fCompiler; }
|
||||
|
||||
/**
|
||||
* Returns the IRGenerator used by DSL operations in the current thread.
|
||||
*/
|
||||
static SkSL::IRGenerator& IRGenerator();
|
||||
|
||||
/**
|
||||
* Returns the Context used by DSL operations in the current thread.
|
||||
*/
|
||||
static SkSL::Context& Context();
|
||||
|
||||
/**
|
||||
* Returns the Settings used by DSL operations in the current thread.
|
||||
*/
|
||||
static SkSL::ProgramSettings& Settings();
|
||||
|
||||
/**
|
||||
* Returns the Program::Inputs used by the current thread.
|
||||
*/
|
||||
static SkSL::Program::Inputs& Inputs();
|
||||
|
||||
/**
|
||||
* Returns the collection to which DSL program elements in this thread should be appended.
|
||||
*/
|
||||
static std::vector<std::unique_ptr<SkSL::ProgramElement>>& ProgramElements() {
|
||||
return Instance().fProgramElements;
|
||||
}
|
||||
|
||||
static std::vector<const ProgramElement*>& SharedElements() {
|
||||
return Instance().fSharedElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SymbolTable of the current thread's IRGenerator.
|
||||
*/
|
||||
static const std::shared_ptr<SkSL::SymbolTable>& SymbolTable();
|
||||
|
||||
/**
|
||||
* Returns the current memory pool.
|
||||
*/
|
||||
static std::unique_ptr<Pool>& MemoryPool() { return Instance().fPool; }
|
||||
|
||||
/**
|
||||
* Returns the current modifiers pool.
|
||||
*/
|
||||
static std::unique_ptr<ModifiersPool>& GetModifiersPool() { return Instance().fModifiersPool; }
|
||||
|
||||
/**
|
||||
* Returns the current ProgramConfig.
|
||||
*/
|
||||
static std::unique_ptr<ProgramConfig>& GetProgramConfig() { return Instance().fConfig; }
|
||||
|
||||
static bool IsModule() { return GetProgramConfig()->fIsBuiltinCode; }
|
||||
|
||||
static void Reset();
|
||||
|
||||
/**
|
||||
* Returns the final pointer to a pooled Modifiers object that should be used to represent the
|
||||
* given modifiers.
|
||||
*/
|
||||
static const SkSL::Modifiers* Modifiers(const SkSL::Modifiers& modifiers);
|
||||
|
||||
/**
|
||||
* Returns the SkSL variable corresponding to a DSL var.
|
||||
*/
|
||||
static const SkSL::Variable* Var(DSLVarBase& var);
|
||||
|
||||
/**
|
||||
* Creates an SkSL variable corresponding to a DSLParameter.
|
||||
*/
|
||||
static std::unique_ptr<SkSL::Variable> CreateParameterVar(DSLParameter& var);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the SkSL declaration corresponding to a DSLVar.
|
||||
*/
|
||||
static std::unique_ptr<SkSL::Statement> Declaration(DSLVarBase& var);
|
||||
|
||||
/**
|
||||
* For use in testing only: marks the variable as having been declared, so that it can be
|
||||
* destroyed without generating errors.
|
||||
*/
|
||||
static void MarkDeclared(DSLVarBase& var);
|
||||
|
||||
/**
|
||||
* Returns the (possibly mangled) final name that should be used for an entity with the given
|
||||
* raw name.
|
||||
*/
|
||||
static skstd::string_view Name(skstd::string_view name);
|
||||
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
/**
|
||||
* Returns the fragment processor for which DSL output is being generated for the current
|
||||
* thread.
|
||||
*/
|
||||
static GrFragmentProcessor::ProgramImpl* CurrentProcessor() {
|
||||
SkASSERTF(!Instance().fStack.empty(), "This feature requires a FragmentProcessor");
|
||||
return Instance().fStack.top().fProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the EmitArgs for fragment processor output in the current thread.
|
||||
*/
|
||||
static GrFragmentProcessor::ProgramImpl::EmitArgs* CurrentEmitArgs() {
|
||||
SkASSERTF(!Instance().fStack.empty(), "This feature requires a FragmentProcessor");
|
||||
return Instance().fStack.top().fEmitArgs;
|
||||
}
|
||||
|
||||
static bool InFragmentProcessor() {
|
||||
return !Instance().fStack.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes a new processor / emitArgs pair for the current thread.
|
||||
*/
|
||||
static void StartFragmentProcessor(GrFragmentProcessor::ProgramImpl* processor,
|
||||
GrFragmentProcessor::ProgramImpl::EmitArgs* emitArgs);
|
||||
|
||||
/**
|
||||
* Pops the processor / emitArgs pair associated with the current thread.
|
||||
*/
|
||||
static void EndFragmentProcessor();
|
||||
|
||||
static GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLGlobalVar& var);
|
||||
#else
|
||||
static bool InFragmentProcessor() {
|
||||
return false;
|
||||
}
|
||||
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
|
||||
/**
|
||||
* Adds a new declaration into an existing declaration statement. This either turns the original
|
||||
* declaration into an unscoped block or, if it already was, appends a new statement to the end
|
||||
* of it.
|
||||
*/
|
||||
static void AddVarDeclaration(DSLStatement& existing, DSLVar& additional);
|
||||
|
||||
/**
|
||||
* Returns the ErrorReporter associated with the current thread. This object will be notified
|
||||
* when any DSL errors occur.
|
||||
*/
|
||||
static ErrorReporter& GetErrorReporter() {
|
||||
return *Context().fErrors;
|
||||
}
|
||||
|
||||
static void SetErrorReporter(ErrorReporter* errorReporter);
|
||||
|
||||
/**
|
||||
* Notifies the current ErrorReporter that a DSL error has occurred. The default error handler
|
||||
* prints the message to stderr and aborts.
|
||||
*/
|
||||
static void ReportError(skstd::string_view msg, PositionInfo info = PositionInfo::Capture());
|
||||
|
||||
/**
|
||||
* Returns whether name mangling is enabled. Mangling is important for the DSL because its
|
||||
* variables normally all go into the same symbol table; for instance if you were to translate
|
||||
@ -234,52 +53,52 @@ public:
|
||||
* with x1 and x2 ending up in the same symbol table. This is fine as long as their effective
|
||||
* names are different, so mangling prevents this situation from causing problems.
|
||||
*/
|
||||
static bool ManglingEnabled() {
|
||||
return Instance().fSettings.fDSLMangling;
|
||||
}
|
||||
static bool ManglingEnabled();
|
||||
|
||||
static skstd::string_view Name(skstd::string_view name);
|
||||
|
||||
/**
|
||||
* Returns the SkSL variable corresponding to a DSL var.
|
||||
*/
|
||||
static const SkSL::Variable* Var(DSLVarBase& var);
|
||||
|
||||
/**
|
||||
* Creates an SkSL variable corresponding to a DSLParameter.
|
||||
*/
|
||||
static std::unique_ptr<SkSL::Variable> CreateParameterVar(DSLParameter& var);
|
||||
|
||||
/**
|
||||
* Returns the SkSL declaration corresponding to a DSLVar.
|
||||
*/
|
||||
static std::unique_ptr<SkSL::Statement> Declaration(DSLVarBase& var);
|
||||
|
||||
/**
|
||||
* For use in testing only: marks the variable as having been declared, so that it can be
|
||||
* destroyed without generating errors.
|
||||
*/
|
||||
static void MarkDeclared(DSLVarBase& var);
|
||||
|
||||
/**
|
||||
* Returns whether DSLVars should automatically be marked declared upon creation. This is used
|
||||
* to simplify testing.
|
||||
*/
|
||||
static bool MarkVarsDeclared() {
|
||||
return Instance().fSettings.fDSLMarkVarsDeclared;
|
||||
}
|
||||
static bool MarkVarsDeclared();
|
||||
|
||||
/**
|
||||
* Forwards any pending errors to the DSL ErrorReporter.
|
||||
* Adds a new declaration into an existing declaration statement. This either turns the original
|
||||
* declaration into an unscoped block or, if it already was, appends a new statement to the end
|
||||
* of it.
|
||||
*/
|
||||
static void ReportErrors(PositionInfo pos);
|
||||
static void AddVarDeclaration(DSLStatement& existing, DSLVar& additional);
|
||||
|
||||
static DSLWriter& Instance();
|
||||
/**
|
||||
* Clears any elements or symbols which have been output.
|
||||
*/
|
||||
static void Reset();
|
||||
|
||||
static void SetInstance(std::unique_ptr<DSLWriter> instance);
|
||||
|
||||
private:
|
||||
class DefaultErrorReporter : public ErrorReporter {
|
||||
void handleError(skstd::string_view msg, PositionInfo pos) override;
|
||||
};
|
||||
|
||||
std::unique_ptr<SkSL::ProgramConfig> fConfig;
|
||||
std::unique_ptr<SkSL::ModifiersPool> fModifiersPool;
|
||||
SkSL::Compiler* fCompiler;
|
||||
std::unique_ptr<Pool> fPool;
|
||||
SkSL::ProgramConfig* fOldConfig;
|
||||
SkSL::ModifiersPool* fOldModifiersPool;
|
||||
std::vector<std::unique_ptr<SkSL::ProgramElement>> fProgramElements;
|
||||
std::vector<const SkSL::ProgramElement*> fSharedElements;
|
||||
DefaultErrorReporter fDefaultErrorReporter;
|
||||
ErrorReporter& fOldErrorReporter;
|
||||
ProgramSettings fSettings;
|
||||
Mangler fMangler;
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
struct StackFrame {
|
||||
GrFragmentProcessor::ProgramImpl* fProcessor;
|
||||
GrFragmentProcessor::ProgramImpl::EmitArgs* fEmitArgs;
|
||||
SkSL::StatementArray fSavedDeclarations;
|
||||
};
|
||||
std::stack<StackFrame, std::list<StackFrame>> fStack;
|
||||
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
static GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLGlobalVar& var);
|
||||
#endif
|
||||
|
||||
friend class DSLCore;
|
||||
friend class DSLVar;
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "src/sksl/SkSLContext.h"
|
||||
#include "src/sksl/SkSLIntrinsicMap.h"
|
||||
#include "src/sksl/SkSLProgramSettings.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/ir/SkSLFunctionCall.h"
|
||||
#include "src/sksl/ir/SkSLFunctionDefinition.h"
|
||||
#include "src/sksl/ir/SkSLReturnStatement.h"
|
||||
@ -64,7 +64,7 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
|
||||
this->copyIntrinsicIfNeeded(*f);
|
||||
}
|
||||
|
||||
dsl::DSLWriter::SharedElements().push_back(found);
|
||||
ThreadContext::SharedElements().push_back(found);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
|
||||
const FunctionDeclaration& func = expr.as<FunctionCall>().function();
|
||||
if (func.isBuiltin()) {
|
||||
if (func.intrinsicKind() == k_dFdy_IntrinsicKind) {
|
||||
dsl::DSLWriter::Inputs().fUseFlipRTUniform = true;
|
||||
ThreadContext::Inputs().fUseFlipRTUniform = true;
|
||||
}
|
||||
if (func.definition()) {
|
||||
fReferencedIntrinsics->insert(&func);
|
||||
|
@ -11,8 +11,8 @@
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLContext.h"
|
||||
#include "src/sksl/SkSLIntrinsicMap.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/analysis/SkSLProgramVisitor.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
#include "src/sksl/ir/SkSLFunctionDefinition.h"
|
||||
#include "src/sksl/ir/SkSLInterfaceBlock.h"
|
||||
#include "src/sksl/ir/SkSLVarDeclarations.h"
|
||||
@ -67,7 +67,7 @@ void FindAndDeclareBuiltinVariables(const Context& context,
|
||||
};
|
||||
|
||||
BuiltinVariableScanner scanner(context);
|
||||
for (auto& e : dsl::DSLWriter::ProgramElements()) {
|
||||
for (auto& e : ThreadContext::ProgramElements()) {
|
||||
scanner.visitProgramElement(*e);
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "src/gpu/GrGpu.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLIRGenerator.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
|
||||
#include "tests/Test.h"
|
||||
@ -42,7 +43,7 @@ public:
|
||||
msg.data());
|
||||
REPORTER_ASSERT(fReporter, pos.line() == fLine,
|
||||
"Line number mismatch: expected %d, but received %d\n", fLine, pos.line());
|
||||
DSLWriter::Compiler().handleError(msg, pos);
|
||||
SkSL::ThreadContext::Compiler().handleError(msg, pos);
|
||||
fMsg = nullptr;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "src/gpu/GrDirectContextPriv.h"
|
||||
#include "src/gpu/GrGpu.h"
|
||||
#include "src/sksl/SkSLIRGenerator.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/dsl/priv/DSLWriter.h"
|
||||
|
||||
#include "tests/Test.h"
|
||||
@ -1250,14 +1251,15 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDecrement, r, ctxInfo) {
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLCall, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
|
||||
{
|
||||
DSLExpression sqrt(DSLWriter::IRGenerator().convertIdentifier(/*line=*/-1, "sqrt"));
|
||||
DSLExpression sqrt(SkSL::ThreadContext::IRGenerator().convertIdentifier(/*line=*/-1,
|
||||
"sqrt"));
|
||||
SkTArray<DSLWrapper<DSLExpression>> args;
|
||||
args.emplace_back(16);
|
||||
EXPECT_EQUAL(sqrt(std::move(args)), "4.0"); // sqrt(16) gets optimized to 4
|
||||
}
|
||||
|
||||
{
|
||||
DSLExpression pow(DSLWriter::IRGenerator().convertIdentifier(/*line=*/-1, "pow"));
|
||||
DSLExpression pow(SkSL::ThreadContext::IRGenerator().convertIdentifier(/*line=*/-1, "pow"));
|
||||
DSLVar a(kFloat_Type, "a");
|
||||
DSLVar b(kFloat_Type, "b");
|
||||
SkTArray<DSLWrapper<DSLExpression>> args;
|
||||
@ -1289,8 +1291,8 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBreak, r, ctxInfo) {
|
||||
If(i > 5, Break())
|
||||
))
|
||||
);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0],
|
||||
"void success() { for (int i = 0; (i < 10); ++i) { if ((i > 5)) break; } }");
|
||||
|
||||
{
|
||||
@ -1309,8 +1311,8 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLContinue, r, ctxInfo) {
|
||||
If(i < 5, Continue())
|
||||
))
|
||||
);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0],
|
||||
"void success() { for (int i = 0; (i < 10); ++i) { if ((i < 5)) continue; } }");
|
||||
|
||||
{
|
||||
@ -1339,25 +1341,25 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDeclare, r, ctxInfo) {
|
||||
|
||||
{
|
||||
DSLWriter::Reset();
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().empty());
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().empty());
|
||||
GlobalVar a(kHalf4_Type, "a"), b(kHalf4_Type, "b", Half4(1));
|
||||
Declare(a);
|
||||
Declare(b);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "half4 a;");
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[1], "half4 b = half4(1.0);");
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0], "half4 a;");
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[1], "half4 b = half4(1.0);");
|
||||
}
|
||||
|
||||
{
|
||||
DSLWriter::Reset();
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().empty());
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().empty());
|
||||
SkTArray<GlobalVar> vars;
|
||||
vars.push_back(GlobalVar(kHalf4_Type, "a"));
|
||||
vars.push_back(GlobalVar(kHalf4_Type, "b", Half4(1)));
|
||||
Declare(vars);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "half4 a;");
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[1], "half4 b = half4(1.0);");
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0], "half4 a;");
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[1], "half4 b = half4(1.0);");
|
||||
}
|
||||
|
||||
{
|
||||
@ -1389,9 +1391,9 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDeclareGlobal, r, ctxInfo) {
|
||||
Declare(x);
|
||||
DSLGlobalVar y(kUniform_Modifier, kFloat2_Type, "y");
|
||||
Declare(y);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "int x = 0;");
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[1], "uniform float2 y;");
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0], "int x = 0;");
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[1], "uniform float2 y;");
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDiscard, r, ctxInfo) {
|
||||
@ -1451,8 +1453,8 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFunction, r, ctxInfo) {
|
||||
DSLFunction(kVoid_Type, "main", coords).define(
|
||||
sk_FragColor() = Half4(coords, 0, 1)
|
||||
);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0],
|
||||
"void main(float2 coords) { (sk_FragColor = half4(half2(coords), 0.0, 1.0)); }");
|
||||
|
||||
{
|
||||
@ -1463,8 +1465,9 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFunction, r, ctxInfo) {
|
||||
Return(x * x)
|
||||
);
|
||||
EXPECT_EQUAL(sqr(sk_FragCoord().x()), "sqr(sk_FragCoord.x)");
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "float sqr(float x) { return (x * x); }");
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0],
|
||||
"float sqr(float x) { return (x * x); }");
|
||||
}
|
||||
|
||||
{
|
||||
@ -1477,8 +1480,8 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLFunction, r, ctxInfo) {
|
||||
);
|
||||
EXPECT_EQUAL(dot(Float2(1.0f, 2.0f), Float2(3.0f, 4.0f)),
|
||||
"dot(float2(1.0, 2.0), float2(3.0, 4.0))");
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0],
|
||||
"float2 dot(float2 x, float2 y) { return ((x * x) + (y * y)); }");
|
||||
}
|
||||
|
||||
@ -1571,23 +1574,23 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLInterfaceBlock, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
|
||||
DSLGlobalVar intf = InterfaceBlock(kUniform_Modifier, "InterfaceBlock1",
|
||||
{ Field(kFloat_Type, "a"), Field(kInt_Type, "b") });
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements().back(),
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements().back(),
|
||||
"uniform InterfaceBlock1 { float a; int b; };");
|
||||
EXPECT_EQUAL(intf.field("a"), "InterfaceBlock1.a");
|
||||
|
||||
DSLGlobalVar intf2 = InterfaceBlock(kUniform_Modifier, "InterfaceBlock2",
|
||||
{ Field(kFloat2_Type, "x"), Field(kHalf2x2_Type, "y") },
|
||||
"blockVar");
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements().back(),
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements().back(),
|
||||
"uniform InterfaceBlock2 { float2 x; half2x2 y; } blockVar;");
|
||||
EXPECT_EQUAL(intf2.field("x"), "blockVar.x");
|
||||
|
||||
DSLGlobalVar intf3 = InterfaceBlock(kUniform_Modifier, "InterfaceBlock3",
|
||||
{ Field(kFloat_Type, "z") },"arrayVar", 4);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 3);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements().back(),
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 3);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements().back(),
|
||||
"uniform InterfaceBlock3 { float z; } arrayVar[4];");
|
||||
EXPECT_EQUAL(intf3[1].field("z"), "arrayVar[1].z");
|
||||
}
|
||||
@ -1983,10 +1986,10 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLStruct, r, ctxInfo) {
|
||||
result.field("a")[0] = result.field("x"),
|
||||
Return(result)
|
||||
);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0],
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0],
|
||||
"struct SimpleStruct { float x; bool b; float[3] a; };");
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[1],
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[1],
|
||||
"SimpleStruct returnStruct() { SimpleStruct result; (result.x = 123.0);"
|
||||
"(result.b = (result.x > 0.0)); (result.a[0] = result.x); return result; }");
|
||||
|
||||
@ -1994,8 +1997,8 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLStruct, r, ctxInfo) {
|
||||
Field(kInt_Type, "x"),
|
||||
Field(simpleStruct, "simple")
|
||||
);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 3);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[2],
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 3);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[2],
|
||||
"struct NestedStruct { int x; SimpleStruct simple; };");
|
||||
}
|
||||
|
||||
@ -2021,8 +2024,8 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLRTAdjust, r, ctxInfo) {
|
||||
DSLFunction(kVoid_Type, "main").define(
|
||||
sk_Position() = Half4(0)
|
||||
);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[1],
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[1],
|
||||
"void main() {"
|
||||
"(sk_PerVertex.sk_Position = float4(0.0));"
|
||||
"(sk_PerVertex.sk_Position = float4(((sk_PerVertex.sk_Position.xy * sk_RTAdjust.xz) + "
|
||||
@ -2033,13 +2036,13 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLRTAdjust, r, ctxInfo) {
|
||||
{
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), no_mark_vars_declared(),
|
||||
SkSL::ProgramKind::kVertex);
|
||||
REPORTER_ASSERT(r, !DSLWriter::IRGenerator().haveRTAdjustInterfaceBlock());
|
||||
REPORTER_ASSERT(r, !SkSL::ThreadContext::IRGenerator().haveRTAdjustInterfaceBlock());
|
||||
|
||||
DSLGlobalVar intf = InterfaceBlock(kUniform_Modifier, "uniforms",
|
||||
{ Field(kInt_Type, "unused"),
|
||||
Field(kFloat4_Type, "sk_RTAdjust") });
|
||||
REPORTER_ASSERT(r, DSLWriter::IRGenerator().haveRTAdjustInterfaceBlock());
|
||||
REPORTER_ASSERT(r, DSLWriter::IRGenerator().getRTAdjustFieldIndex() == 1);
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::IRGenerator().haveRTAdjustInterfaceBlock());
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::IRGenerator().getRTAdjustFieldIndex() == 1);
|
||||
}
|
||||
|
||||
{
|
||||
@ -2098,30 +2101,32 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLPrototypes, r, ctxInfo) {
|
||||
{
|
||||
DSLParameter x(kFloat_Type, "x");
|
||||
DSLFunction sqr(kFloat_Type, "sqr", x);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "float sqr(float x);");
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0], "float sqr(float x);");
|
||||
sqr.define(
|
||||
Return(x * x)
|
||||
);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "float sqr(float x) { return (x * x); }");
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0],
|
||||
"float sqr(float x) { return (x * x); }");
|
||||
}
|
||||
|
||||
{
|
||||
DSLWriter::Reset();
|
||||
DSLParameter x(kFloat_Type, "x");
|
||||
DSLFunction sqr(kFloat_Type, "sqr", x);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "float sqr(float x);");
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0], "float sqr(float x);");
|
||||
DSLFunction(kVoid_Type, "main").define(sqr(5));
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "float sqr(float x);");
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[1], "void main() { sqr(5.0); }");
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 2);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0], "float sqr(float x);");
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[1], "void main() { sqr(5.0); }");
|
||||
sqr.define(
|
||||
Return(x * x)
|
||||
);
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 3);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[2], "float sqr(float x) { return (x * x); }");
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 3);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[2],
|
||||
"float sqr(float x) { return (x * x); }");
|
||||
|
||||
const char* source = "source test";
|
||||
std::unique_ptr<SkSL::Program> p = ReleaseProgram(std::make_unique<SkSL::String>(source));
|
||||
@ -2138,15 +2143,16 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLPrototypes, r, ctxInfo) {
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLExtension, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
|
||||
AddExtension("test_extension");
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "#extension test_extension : enable");
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0], "#extension test_extension : enable");
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLModifiersDeclaration, r, ctxInfo) {
|
||||
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
|
||||
Declare(Modifiers(Layout().blendSupportAllEquations(), kOut_Modifier));
|
||||
REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*DSLWriter::ProgramElements()[0], "layout(blend_support_all_equations) out;");
|
||||
REPORTER_ASSERT(r, SkSL::ThreadContext::ProgramElements().size() == 1);
|
||||
EXPECT_EQUAL(*SkSL::ThreadContext::ProgramElements()[0],
|
||||
"layout(blend_support_all_equations) out;");
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLES3Types, r, ctxInfo) {
|
||||
|
Loading…
Reference in New Issue
Block a user