Improved whole-program dehydration and rehydration
This adds a Dehydrator.write(Program) to mirror the Rehydrator's program() method and simplifies the API. Change-Id: I1b6d6b722d0ce8e6a292132522f806e43d49ce85 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/502704 Reviewed-by: John Stiles <johnstiles@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
47045c9e06
commit
744116876e
@ -603,6 +603,34 @@ void Dehydrator::write(const std::vector<std::unique_ptr<ProgramElement>>& eleme
|
||||
this->writeCommand(Rehydrator::kElementsComplete_Command);
|
||||
}
|
||||
|
||||
void Dehydrator::write(const Program& program) {
|
||||
this->writeCommand(Rehydrator::kProgram_Command);
|
||||
|
||||
// Collect the symbol tables so we can write out the count
|
||||
std::vector<SymbolTable*> symbolTables;
|
||||
SymbolTable* symbols = program.fSymbols.get();
|
||||
while (symbols) {
|
||||
symbolTables.push_back(symbols);
|
||||
symbols = symbols->fParent.get();
|
||||
}
|
||||
this->writeU8(symbolTables.size());
|
||||
|
||||
// Write the symbol tables from the root down
|
||||
for (int i = symbolTables.size() - 1; i >= 0; --i) {
|
||||
this->write(*symbolTables[i]);
|
||||
}
|
||||
|
||||
// Write the elements
|
||||
this->write(program.fOwnedElements);
|
||||
|
||||
// Write the inputs
|
||||
struct KnownSkSLProgramInputs { bool useRTFlipUniform; };
|
||||
// Since it would be easy to forget to update this code in the face of Inputs changes and any
|
||||
// resulting bugs could be very subtle, assert that the struct hasn't changed:
|
||||
static_assert(sizeof(SkSL::Program::Inputs) == sizeof(KnownSkSLProgramInputs));
|
||||
this->writeU8(program.fInputs.fUseFlipRTUniform);
|
||||
}
|
||||
|
||||
void Dehydrator::finish(OutputStream& out) {
|
||||
out.write16(Rehydrator::kVersion);
|
||||
std::string stringBuffer = fStringBuffer.str();
|
||||
|
@ -23,6 +23,7 @@ namespace SkSL {
|
||||
|
||||
class AnyConstructor;
|
||||
class Expression;
|
||||
struct Program;
|
||||
class ProgramElement;
|
||||
class Statement;
|
||||
class Symbol;
|
||||
@ -45,6 +46,8 @@ public:
|
||||
SkASSERT(fSymbolMap.size() == 1);
|
||||
}
|
||||
|
||||
void write(const Program& program);
|
||||
|
||||
void write(const SymbolTable& symbols);
|
||||
|
||||
void write(const std::vector<std::unique_ptr<ProgramElement>>& elements);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "include/private/SkSLStatement.h"
|
||||
#include "src/sksl/SkSLAnalysis.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/ir/SkSLBinaryExpression.h"
|
||||
#include "src/sksl/ir/SkSLBreakStatement.h"
|
||||
#include "src/sksl/ir/SkSLConstructor.h"
|
||||
@ -89,8 +90,7 @@ Rehydrator::Rehydrator(const Compiler& compiler, const uint8_t* src, size_t leng
|
||||
SkASSERT(fSymbolTable);
|
||||
SkASSERT(fSymbolTable->isBuiltin());
|
||||
fIP = src;
|
||||
uint16_t version = this->readU16();
|
||||
(void)version;
|
||||
[[maybe_unused]] uint16_t version = this->readU16();
|
||||
SkASSERTF(version == kVersion, "Dehydrated file is an unsupported version (current version is "
|
||||
"%d, found version %d)", kVersion, version);
|
||||
fStringStart = fIP;
|
||||
@ -98,6 +98,13 @@ Rehydrator::Rehydrator(const Compiler& compiler, const uint8_t* src, size_t leng
|
||||
fIP += this->readU16();
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
Rehydrator::~Rehydrator() {
|
||||
// ensure that we have read the expected number of bytes
|
||||
SkASSERT(fIP == fEnd);
|
||||
}
|
||||
#endif
|
||||
|
||||
Layout Rehydrator::layout() {
|
||||
switch (this->readU8()) {
|
||||
case kBuiltinLayout_Command: {
|
||||
@ -259,16 +266,16 @@ const Type* Rehydrator::type() {
|
||||
return (const Type*) result;
|
||||
}
|
||||
|
||||
std::unique_ptr<Program> Rehydrator::program(int symbolTableCount,
|
||||
std::unique_ptr<std::string> source,
|
||||
std::unique_ptr<ProgramConfig> config,
|
||||
std::vector<const ProgramElement*> sharedElements,
|
||||
std::unique_ptr<ModifiersPool> modifiers,
|
||||
std::unique_ptr<Pool> pool,
|
||||
Program::Inputs inputs) {
|
||||
std::unique_ptr<Program> Rehydrator::program(
|
||||
const std::vector<const ProgramElement*>* sharedElements) {
|
||||
[[maybe_unused]] uint8_t command = this->readU8();
|
||||
SkASSERT(command == kProgram_Command);
|
||||
uint8_t symbolTableCount = this->readU8();
|
||||
ProgramConfig* oldConfig = fContext->fConfig;
|
||||
ModifiersPool* oldModifiersPool = fContext->fModifiersPool;
|
||||
auto config = std::make_unique<ProgramConfig>();
|
||||
fContext->fConfig = config.get();
|
||||
auto modifiers = std::make_unique<ModifiersPool>();
|
||||
fContext->fModifiersPool = modifiers.get();
|
||||
for (int i = 0; i < symbolTableCount; ++i) {
|
||||
this->symbolTable();
|
||||
@ -276,9 +283,13 @@ std::unique_ptr<Program> Rehydrator::program(int symbolTableCount,
|
||||
std::vector<std::unique_ptr<ProgramElement>> elements = this->elements();
|
||||
fContext->fConfig = oldConfig;
|
||||
fContext->fModifiersPool = oldModifiersPool;
|
||||
return std::make_unique<Program>(std::move(source), std::move(config), fContext,
|
||||
std::move(elements), std::move(sharedElements), std::move(modifiers), fSymbolTable,
|
||||
std::move(pool), inputs);
|
||||
if (!sharedElements) {
|
||||
sharedElements = &ThreadContext::SharedElements();
|
||||
}
|
||||
Program::Inputs inputs;
|
||||
inputs.fUseFlipRTUniform = this->readU8();
|
||||
return std::make_unique<Program>(nullptr, std::move(config), fContext, std::move(elements),
|
||||
*sharedElements, std::move(modifiers), fSymbolTable, /*pool=*/nullptr, inputs);
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<ProgramElement>> Rehydrator::elements() {
|
||||
|
@ -34,7 +34,7 @@ class Type;
|
||||
*/
|
||||
class Rehydrator {
|
||||
public:
|
||||
static constexpr uint16_t kVersion = 5;
|
||||
static constexpr uint16_t kVersion = 6;
|
||||
|
||||
enum Command {
|
||||
// uint16 id, Type componentType, uint8 count
|
||||
@ -110,6 +110,9 @@ public:
|
||||
kPostfix_Command,
|
||||
// uint8 op, Expression operand
|
||||
kPrefix_Command,
|
||||
// uint8_t symbolTableCount, SymbolTable[] symbolTables, Elements elements,
|
||||
// bool useFlipRTUniform
|
||||
kProgram_Command,
|
||||
// Expression value
|
||||
kReturn_Command,
|
||||
// String name, Expression value
|
||||
@ -149,20 +152,20 @@ public:
|
||||
Rehydrator(const Compiler& compiler, const uint8_t* src, size_t length,
|
||||
std::shared_ptr<SymbolTable> base = nullptr);
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
~Rehydrator();
|
||||
#endif
|
||||
|
||||
// Reads a symbol table and makes it current (inheriting from the previous current table)
|
||||
std::shared_ptr<SymbolTable> symbolTable();
|
||||
|
||||
// Reads a collection of program elements and returns it
|
||||
std::vector<std::unique_ptr<ProgramElement>> elements();
|
||||
|
||||
// Reads an entire program
|
||||
std::unique_ptr<Program> program(int symbolTableCount,
|
||||
std::unique_ptr<std::string> source,
|
||||
std::unique_ptr<ProgramConfig> config,
|
||||
std::vector<const ProgramElement*> sharedElements,
|
||||
std::unique_ptr<ModifiersPool> modifiers,
|
||||
std::unique_ptr<Pool> pool,
|
||||
Program::Inputs inputs);
|
||||
// Reads an entire program. If the sharedElements are not provided, they will be pulled from the
|
||||
// current ThreadContext.
|
||||
std::unique_ptr<Program> program(
|
||||
const std::vector<const ProgramElement*>* sharedElements = nullptr);
|
||||
|
||||
private:
|
||||
// If this ID appears in a symbol table, it means the corresponding symbol isn't actually
|
||||
|
@ -1,4 +1,4 @@
|
||||
static uint8_t SKSL_INCLUDE_sksl_frag[] = {5,0,96,0,
|
||||
static uint8_t SKSL_INCLUDE_sksl_frag[] = {6,0,96,0,
|
||||
12,115,107,95,70,114,97,103,67,111,111,114,100,
|
||||
6,102,108,111,97,116,52,
|
||||
12,115,107,95,67,108,111,99,107,119,105,115,101,
|
||||
@ -7,52 +7,52 @@ static uint8_t SKSL_INCLUDE_sksl_frag[] = {5,0,96,0,
|
||||
5,104,97,108,102,52,
|
||||
16,115,107,95,76,97,115,116,70,114,97,103,67,111,108,111,114,
|
||||
21,115,107,95,83,101,99,111,110,100,97,114,121,70,114,97,103,67,111,108,111,114,
|
||||
49,1,5,0,
|
||||
53,1,0,
|
||||
50,1,5,0,
|
||||
54,1,0,
|
||||
37,
|
||||
36,0,2,0,0,255,255,255,255,255,255,255,15,0,255,16,2,0,
|
||||
50,2,0,15,0,0,
|
||||
53,3,0,
|
||||
51,2,0,15,0,0,
|
||||
54,3,0,
|
||||
37,
|
||||
36,0,2,0,0,255,255,255,255,255,255,255,17,0,255,16,22,0,
|
||||
50,4,0,35,0,0,
|
||||
53,5,0,
|
||||
51,4,0,35,0,0,
|
||||
54,5,0,
|
||||
37,
|
||||
36,144,2,0,0,0,255,255,255,255,0,255,17,39,255,32,40,0,
|
||||
50,6,0,53,0,0,
|
||||
53,7,0,
|
||||
51,6,0,53,0,0,
|
||||
54,7,0,
|
||||
37,
|
||||
36,0,2,0,0,255,255,255,255,255,255,255,24,39,255,0,59,0,
|
||||
48,6,0,0,
|
||||
53,8,0,
|
||||
49,6,0,0,
|
||||
54,8,0,
|
||||
37,
|
||||
36,0,2,0,0,255,255,255,255,255,255,255,28,39,255,32,76,0,
|
||||
48,6,0,0,5,0,
|
||||
49,6,0,0,5,0,
|
||||
1,0,
|
||||
2,0,
|
||||
0,0,
|
||||
3,0,
|
||||
4,0,
|
||||
20,
|
||||
55,
|
||||
54,1,0,
|
||||
48,2,0,0,
|
||||
57,
|
||||
55,
|
||||
54,3,0,
|
||||
48,4,0,0,
|
||||
57,
|
||||
55,
|
||||
54,5,0,
|
||||
48,6,0,0,
|
||||
57,
|
||||
55,
|
||||
54,7,0,
|
||||
48,6,0,0,
|
||||
57,
|
||||
55,
|
||||
54,8,0,
|
||||
48,6,0,0,
|
||||
57,
|
||||
56,
|
||||
55,1,0,
|
||||
49,2,0,0,
|
||||
58,
|
||||
56,
|
||||
55,3,0,
|
||||
49,4,0,0,
|
||||
58,
|
||||
56,
|
||||
55,5,0,
|
||||
49,6,0,0,
|
||||
58,
|
||||
56,
|
||||
55,7,0,
|
||||
49,6,0,0,
|
||||
58,
|
||||
56,
|
||||
55,8,0,
|
||||
49,6,0,0,
|
||||
58,
|
||||
21,};
|
||||
static constexpr size_t SKSL_INCLUDE_sksl_frag_LENGTH = sizeof(SKSL_INCLUDE_sksl_frag);
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,16 +1,16 @@
|
||||
static uint8_t SKSL_INCLUDE_sksl_rt_shader[] = {5,0,20,0,
|
||||
static uint8_t SKSL_INCLUDE_sksl_rt_shader[] = {6,0,20,0,
|
||||
12,115,107,95,70,114,97,103,67,111,111,114,100,
|
||||
6,102,108,111,97,116,52,
|
||||
49,1,1,0,
|
||||
53,1,0,
|
||||
50,1,1,0,
|
||||
54,1,0,
|
||||
37,
|
||||
36,0,2,0,0,255,255,255,255,255,255,255,15,0,255,0,2,0,
|
||||
50,2,0,15,0,0,1,0,
|
||||
51,2,0,15,0,0,1,0,
|
||||
0,0,
|
||||
20,
|
||||
55,
|
||||
54,1,0,
|
||||
48,2,0,0,
|
||||
57,
|
||||
56,
|
||||
55,1,0,
|
||||
49,2,0,0,
|
||||
58,
|
||||
21,};
|
||||
static constexpr size_t SKSL_INCLUDE_sksl_rt_shader_LENGTH = sizeof(SKSL_INCLUDE_sksl_rt_shader);
|
||||
|
@ -1,4 +1,4 @@
|
||||
static uint8_t SKSL_INCLUDE_sksl_vert[] = {5,0,82,0,
|
||||
static uint8_t SKSL_INCLUDE_sksl_vert[] = {6,0,82,0,
|
||||
12,115,107,95,80,101,114,86,101,114,116,101,120,
|
||||
11,115,107,95,80,111,115,105,116,105,111,110,
|
||||
6,102,108,111,97,116,52,
|
||||
@ -8,42 +8,42 @@ static uint8_t SKSL_INCLUDE_sksl_vert[] = {5,0,82,0,
|
||||
3,105,110,116,
|
||||
13,115,107,95,73,110,115,116,97,110,99,101,73,68,
|
||||
0,
|
||||
49,1,6,0,
|
||||
45,1,0,2,0,2,
|
||||
50,1,6,0,
|
||||
46,1,0,2,0,2,
|
||||
37,
|
||||
36,0,2,0,0,255,255,255,255,255,255,255,0,0,255,0,15,0,
|
||||
50,2,0,27,0,
|
||||
51,2,0,27,0,
|
||||
37,
|
||||
36,0,2,0,0,255,255,255,255,255,255,255,1,0,255,0,34,0,
|
||||
50,3,0,47,0,1,
|
||||
53,4,0,
|
||||
51,3,0,47,0,1,
|
||||
54,4,0,
|
||||
37,
|
||||
16,32,2,0,
|
||||
48,1,0,0,
|
||||
49,1,0,0,
|
||||
23,4,0,0,
|
||||
23,4,0,1,
|
||||
53,5,0,
|
||||
54,5,0,
|
||||
37,
|
||||
36,0,2,0,0,255,255,255,255,255,255,255,42,0,255,16,53,0,
|
||||
50,6,0,65,0,0,
|
||||
53,7,0,
|
||||
51,6,0,65,0,0,
|
||||
54,7,0,
|
||||
37,
|
||||
36,0,2,0,0,255,255,255,255,255,255,255,43,0,255,16,69,0,
|
||||
48,6,0,0,4,0,
|
||||
49,6,0,0,4,0,
|
||||
5,0,
|
||||
3,0,
|
||||
2,0,
|
||||
4,0,
|
||||
20,
|
||||
34,
|
||||
48,4,0,2,0,83,0,0,
|
||||
55,
|
||||
54,5,0,
|
||||
48,6,0,0,
|
||||
57,
|
||||
55,
|
||||
54,7,0,
|
||||
48,6,0,0,
|
||||
57,
|
||||
49,4,0,2,0,83,0,0,
|
||||
56,
|
||||
55,5,0,
|
||||
49,6,0,0,
|
||||
58,
|
||||
56,
|
||||
55,7,0,
|
||||
49,6,0,0,
|
||||
58,
|
||||
21,};
|
||||
static constexpr size_t SKSL_INCLUDE_sksl_vert_LENGTH = sizeof(SKSL_INCLUDE_sksl_vert);
|
||||
|
@ -240,16 +240,13 @@ static void test_rehydrate(skiatest::Reporter* r, const char* testFile) {
|
||||
return;
|
||||
}
|
||||
SkSL::Dehydrator dehydrator;
|
||||
int symbolTableCount = write_symbol_tables(dehydrator, *program->fSymbols);
|
||||
dehydrator.write(program->fOwnedElements);
|
||||
dehydrator.write(*program);
|
||||
SkSL::StringStream stream;
|
||||
dehydrator.finish(stream);
|
||||
|
||||
SkSL::Rehydrator rehydrator(compiler, (const uint8_t*) stream.str().data(),
|
||||
stream.str().length());
|
||||
std::unique_ptr<SkSL::Program> rehydrated = rehydrator.program(symbolTableCount,
|
||||
/*source=*/nullptr, std::make_unique<SkSL::ProgramConfig>(), program->fSharedElements,
|
||||
std::make_unique<SkSL::ModifiersPool>(), /*pool=*/nullptr, program->fInputs);
|
||||
std::unique_ptr<SkSL::Program> rehydrated = rehydrator.program(&program->fSharedElements);
|
||||
REPORTER_ASSERT(r, rehydrated->description() == program->description(),
|
||||
"Mismatch between original and dehydrated/rehydrated:\n-- Original:\n%s\n"
|
||||
"-- Rehydrated:\n%s", program->description().c_str(),
|
||||
|
Loading…
Reference in New Issue
Block a user