Skip to content

Commit

Permalink
vkconfig3: Add layer manifest validation caching
Browse files Browse the repository at this point in the history
  • Loading branch information
christophe-lunarg committed Jul 17, 2024
1 parent 575c6b4 commit 4fbbac9
Show file tree
Hide file tree
Showing 13 changed files with 119 additions and 41 deletions.
17 changes: 15 additions & 2 deletions vkconfig_core/configurator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,15 +302,28 @@ Configurator& Configurator::Get() {
Configurator::Configurator() : environment(), layers(), configurations() {}

Configurator::~Configurator() {
this->UpdateLayersValidationCache();

this->configurations.SaveAllConfigurations();

this->Surrender();
}

void Configurator::UpdateLayersValidationCache() {
this->environment.layers_validated.clear();

for (std::size_t i = 0, n = this->layers.Size(); i < n; ++i) {
const Layer& layer = this->layers.selected_layers[i];

this->environment.layers_validated.insert(
std::make_pair(layer.manifest_path.AbsolutePath(), layer.validated_last_modified));
}
}

bool Configurator::Init() {
// Load simple app settings, the additional search paths, and the
// override app list.
this->layers.LoadAllInstalledLayers();
this->layers.LoadAllInstalledLayers(environment.layers_validated);

if (this->environment.has_crashed) {
this->environment.has_crashed = false;
Expand Down Expand Up @@ -373,7 +386,7 @@ bool Configurator::HasOverride() const {

void Configurator::ResetToDefault(bool hard) {
this->environment.Reset(Environment::CLEAR);
this->layers.LoadAllInstalledLayers();
this->layers.LoadAllInstalledLayers(this->environment.layers_validated);
this->configurations.Reset(this->layers.selected_layers);
}

Expand Down
2 changes: 2 additions & 0 deletions vkconfig_core/configurator.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class Configurator {
void BuildLoaderSettings(const ConfigurationInfo& info, const std::string& executable_path,
std::vector<LoaderSettings>& loader_settings_array) const;

void UpdateLayersValidationCache();

public:
Environment environment;
LayerManager layers;
Expand Down
27 changes: 27 additions & 0 deletions vkconfig_core/environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <QTextStream>

#include <cassert>
#include <iostream>

static const char* GetApplicationSuffix() {
static const char* TABLE[] = {
Expand Down Expand Up @@ -163,6 +164,18 @@ bool Environment::Load() {
this->loader_message_types_flags |= GetLogBit(token.c_str());
}

// layers json object
const QJsonObject& json_layers_object = json_root_object.value("layers").toObject();
const QJsonObject& json_layers_validated_object = json_layers_object.value("validated").toObject();

const QStringList& json_layers_validated_keys = json_layers_validated_object.keys();

for (int i = 0, n = json_layers_validated_keys.length(); i < n; ++i) {
const std::string& manifest_path = json_layers_validated_keys[i].toStdString();
const std::string& last_modified = json_layers_validated_object.value(manifest_path.c_str()).toString().toStdString();
layers_validated.insert(std::make_pair(manifest_path, last_modified));
}

// applications json object
const QJsonObject& json_applications_object = json_root_object.value("applications").toObject();

Expand Down Expand Up @@ -239,9 +252,17 @@ bool Environment::Load() {

bool Environment::Save() const {
const Path& vkconfig_init_path = ::Get(Path::INIT);
if (Path(vkconfig_init_path.AbsoluteDir()).Exists()) {
std::cout << Path(vkconfig_init_path).AbsoluteDir() << " exists." << std::endl;
} else {
std::cout << Path(vkconfig_init_path).AbsoluteDir() << " doesn't exist." << std::endl;
}

QFile file(vkconfig_init_path.AbsolutePath().c_str());
const bool result = file.open(QIODevice::WriteOnly | QIODevice::Text);
if (result == false) {
std::cout << vkconfig_init_path.AbsolutePath().c_str() << std::endl;
}
assert(result);

QJsonObject json_root_object;
Expand Down Expand Up @@ -309,7 +330,13 @@ bool Environment::Save() const {

json_root_object.insert("applications", json_applications_object);

QJsonObject json_layers_paths_object;
for (auto it = this->layers_validated.begin(), end = this->layers_validated.end(); it != end; ++it) {
json_layers_paths_object.insert(it->first.c_str(), it->second.c_str());
}

QJsonObject json_layers_object;
json_layers_object.insert("validated", json_layers_paths_object);

json_root_object.insert("layers", json_layers_object);

Expand Down
1 change: 1 addition & 0 deletions vkconfig_core/environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ class Environment {
Path path_import;

ConfigurationInfo global_configuration;
std::map<std::string, std::string> layers_validated;

private:
Environment(const Environment&) = delete;
Expand Down
20 changes: 12 additions & 8 deletions vkconfig_core/layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ SettingMeta* Layer::Instantiate(SettingMetaSet& meta_set, const std::string& key
return setting_meta;
}

bool Layer::Load(const Path& full_path_to_file, LayerType type) {
bool Layer::Load(const Path& full_path_to_file, const std::map<std::string, std::string>& layers_validated, LayerType type) {
this->type = type; // Set layer type, no way to know this from the json file

if (full_path_to_file.Empty()) {
Expand Down Expand Up @@ -182,10 +182,7 @@ bool Layer::Load(const Path& full_path_to_file, LayerType type) {

const QJsonObject& json_layer_object = ReadObject(json_root_object, "layer");

std::string current_last_modified = full_path_to_file.LastModified();

QSettings settings;
std::string cached_last_modified = settings.value(full_path_to_file.AbsolutePath().c_str()).toString().toStdString();
const std::string& last_modified = full_path_to_file.LastModified();

this->key = ReadStringValue(json_layer_object, "name");

Expand All @@ -197,11 +194,18 @@ bool Layer::Load(const Path& full_path_to_file, LayerType type) {

JsonValidator validator;

const bool should_validate = current_last_modified != cached_last_modified;
std::string cached_last_modified;
auto it = layers_validated.find(this->manifest_path.AbsolutePath());
if (it != layers_validated.end()) {
cached_last_modified = it->second;
}
const bool should_validate = !this->manifest_path.IsBuiltIn() && last_modified != cached_last_modified;
const bool is_valid = should_validate ? validator.Check(json_text) : true;

if (should_validate && is_valid) {
settings.setValue(full_path_to_file.AbsolutePath().c_str(), current_last_modified.c_str());
if (!is_valid) {
this->validated_last_modified.clear();
} else {
this->validated_last_modified = last_modified;
}

const QJsonValue& json_library_path_value = json_layer_object.value("library_path");
Expand Down
6 changes: 5 additions & 1 deletion vkconfig_core/layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class Layer {
Path binary_path;
Version api_version;
std::string implementation_version;
std::string validated_last_modified;
StatusType status;
std::string description;
std::string introduction;
Expand All @@ -75,11 +76,14 @@ class Layer {
std::vector<SettingMeta*> settings;
std::vector<LayerPreset> presets;

bool Load(const Path& full_path_to_file, LayerType type = LAYER_TYPE_EXPLICIT);
bool Load(const Path& full_path_to_file, const std::map<std::string, std::string>& layers_validated,
LayerType type = LAYER_TYPE_EXPLICIT);

private:
Layer& operator=(const Layer&) = delete;

bool IsBuiltIn() const;

std::vector<std::shared_ptr<SettingMeta> > memory; // Settings are deleted when all layers instances are deleted.
};

Expand Down
11 changes: 5 additions & 6 deletions vkconfig_core/layer_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ LayerManager::LayerManager(const std::vector<Path> &user_defined_paths) {
user_defined_paths.end());

this->paths[LAYERS_PATHS_SDK].push_back(::Get(Path::SDK_BIN));

this->LoadAllInstalledLayers();
}

void LayerManager::Clear() { this->selected_layers.clear(); }
Expand All @@ -147,25 +145,26 @@ const Layer *LayerManager::Find(const std::string &layer_name) const {
}

// Find all installed layers on the system.
void LayerManager::LoadAllInstalledLayers() {
void LayerManager::LoadAllInstalledLayers(const std::map<std::string, std::string> &layers_validated) {
this->selected_layers.clear();

for (std::size_t group_index = 0, group_count = this->paths.size(); group_index < group_count; ++group_index) {
const LayerType layer_type = ::GetLayerType(static_cast<LayersPaths>(group_index));

const std::vector<Path> &paths_group = this->paths[group_index];
for (std::size_t i = 0, n = paths_group.size(); i < n; ++i) {
this->LoadLayersFromPath(paths_group[i], layer_type);
this->LoadLayersFromPath(paths_group[i], layers_validated, layer_type);
}
}
}

void LayerManager::LoadLayersFromPath(const Path &layers_path, LayerType type) {
void LayerManager::LoadLayersFromPath(const Path &layers_path, const std::map<std::string, std::string> &layers_validated,
LayerType type) {
const std::vector<Path> &layers_paths = layers_path.IsDir() ? CollectFilePaths(layers_path) : GetVector(layers_path);

for (std::size_t i = 0, n = layers_paths.size(); i < n; ++i) {
Layer layer;
if (layer.Load(layers_paths[i], type)) {
if (layer.Load(layers_paths[i], layers_validated, type)) {
if (this->IsAvailable(layer)) {
continue;
}
Expand Down
6 changes: 4 additions & 2 deletions vkconfig_core/layer_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ class LayerManager {
Layer* Find(const std::string& layer_name);
const Layer* Find(const std::string& layer_name) const;

void LoadAllInstalledLayers();
void LoadLayersFromPath(const Path& layers_path, LayerType type = LAYER_TYPE_EXPLICIT);
void LoadAllInstalledLayers(const std::map<std::string, std::string>& layers_validated);

void LoadLayersFromPath(const Path& layers_path, const std::map<std::string, std::string>& layers_validated,
LayerType type = LAYER_TYPE_EXPLICIT);

std::vector<Layer> selected_layers;

Expand Down
19 changes: 16 additions & 3 deletions vkconfig_core/path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ bool Path::IsFile() const { return QFileInfo(this->data.c_str()).isFile(); }

bool Path::IsDir() const { return QFileInfo(this->data.c_str()).isDir(); }

bool Path::IsBuiltIn() const { return this->data.find(":") == 0; }

Path& Path::operator=(const Path& path) {
this->data = path.data;
return *this;
Expand Down Expand Up @@ -223,7 +225,6 @@ static const Path GetHomePath() {
}

Path path(result);

if (!path.Exists()) {
path.Create();
}
Expand All @@ -238,7 +239,12 @@ static const Path GetAppDataPath() {
};
static_assert(std::size(TABLE) == ENVIRONMENT_COUNT);

return QDir().homePath().toStdString() + TABLE[VKC_ENV];
Path path(QDir().homePath().toStdString() + TABLE[VKC_ENV]);
if (!path.Exists()) {
path.Create();
}

return path;
}

static const Path GetInitPath() {
Expand All @@ -248,7 +254,14 @@ static const Path GetInitPath() {
};
static_assert(std::size(TABLE) == ENVIRONMENT_COUNT);

return GetAppDataPath().RelativePath() + TABLE[VKC_ENV];
Path path(GetAppDataPath().RelativePath() + TABLE[VKC_ENV]);
Path folder(path.AbsoluteDir());

if (!folder.Exists()) {
folder.Create();
}

return path;
}

static const Path GetConfigsPath() {
Expand Down
2 changes: 2 additions & 0 deletions vkconfig_core/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class Path {
bool IsFile() const;
bool IsDir() const;

bool IsBuiltIn() const;

void Clear();
bool Exists() const;
bool Create(bool as_file = false) const;
Expand Down
6 changes: 4 additions & 2 deletions vkconfig_core/test/test_configuration_built_in.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ static bool operator==(const Parameter& a, const Parameter& b) {

static bool operator!=(const std::vector<Parameter>& a, const std::vector<Parameter>& b) { return !(a == b); }

std::map<std::string, std::string> Dummy() { return std::map<std::string, std::string>(); }

struct TestBuilin {
TestBuilin() : environment(), layer_manager() {
this->layer_manager.LoadLayersFromPath(":/sdk");
TestBuilin() : environment(Environment::MODE_UNINITIALIZED), layer_manager() {
this->layer_manager.LoadLayersFromPath(":/sdk", Dummy());
EXPECT_TRUE(!this->layer_manager.selected_layers.empty());
}

Expand Down
20 changes: 11 additions & 9 deletions vkconfig_core/test/test_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ inline SettingMetaString* InstantiateString(Layer& layer, const std::string& key
return static_cast<SettingMetaString*>(layer.Instantiate(layer.settings, key, SETTING_STRING));
}

std::map<std::string, std::string> Dummy() { return std::map<std::string, std::string>(); }

TEST(test_layer, collect_settings) {
Layer layer;

Expand All @@ -58,7 +60,7 @@ TEST(test_layer, collect_settings) {

TEST(test_layer, load_header_overridden) {
Layer layer;
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_00.json", LAYER_TYPE_EXPLICIT);
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_00.json", Dummy(), LAYER_TYPE_EXPLICIT);
ASSERT_TRUE(load_loaded);

EXPECT_EQ(Version(1, 2, 0), layer.file_format_version);
Expand All @@ -76,7 +78,7 @@ TEST(test_layer, load_header_overridden) {

TEST(test_layer, load_header_default) {
Layer layer;
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_01.json", LAYER_TYPE_EXPLICIT);
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_01.json", Dummy(), LAYER_TYPE_EXPLICIT);
ASSERT_TRUE(load_loaded);

EXPECT_EQ(Version(1, 2, 0), layer.file_format_version);
Expand All @@ -94,7 +96,7 @@ TEST(test_layer, load_header_default) {

TEST(test_layer, load_header_override) {
Layer layer;
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_02.json", LAYER_TYPE_EXPLICIT);
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_02.json", Dummy(), LAYER_TYPE_EXPLICIT);
ASSERT_TRUE(load_loaded);

EXPECT_EQ(Version(1, 2, 0), layer.file_format_version);
Expand All @@ -106,7 +108,7 @@ TEST(test_layer, load_header_override) {

TEST(test_layer, load_setting_interit) {
Layer layer;
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_03.json", LAYER_TYPE_EXPLICIT);
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_03.json", Dummy(), LAYER_TYPE_EXPLICIT);
ASSERT_TRUE(load_loaded);

EXPECT_EQ(Version(1, 2, 0), layer.file_format_version);
Expand All @@ -128,7 +130,7 @@ TEST(test_layer, load_setting_interit) {

TEST(test_layer, load_preset_interit) {
Layer layer;
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_04.json", LAYER_TYPE_EXPLICIT);
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_04.json", Dummy(), LAYER_TYPE_EXPLICIT);
ASSERT_TRUE(load_loaded);

EXPECT_EQ(Version(1, 2, 0), layer.file_format_version);
Expand All @@ -148,7 +150,7 @@ TEST(test_layer, load_preset_interit) {

TEST(test_layer, load_setting_children_interit) {
Layer layer;
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_05.json", LAYER_TYPE_EXPLICIT);
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_05.json", Dummy(), LAYER_TYPE_EXPLICIT);
ASSERT_TRUE(load_loaded);

EXPECT_EQ(Version(1, 2, 0), layer.file_format_version);
Expand All @@ -170,7 +172,7 @@ TEST(test_layer, load_setting_children_interit) {

TEST(test_layer, load_setting_enum_interit) {
Layer layer;
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_06.json", LAYER_TYPE_EXPLICIT);
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_test_06.json", Dummy(), LAYER_TYPE_EXPLICIT);
ASSERT_TRUE(load_loaded);

EXPECT_EQ(Version(1, 2, 0), layer.file_format_version);
Expand Down Expand Up @@ -212,7 +214,7 @@ TEST(test_layer, load_setting_enum_interit) {

TEST(test_layer, load_1_1_0_header) {
Layer layer;
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_reference_1_1_0.json", LAYER_TYPE_EXPLICIT);
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_reference_1_1_0.json", Dummy(), LAYER_TYPE_EXPLICIT);
ASSERT_TRUE(load_loaded);

EXPECT_EQ(Version(1, 1, 0), layer.file_format_version);
Expand All @@ -230,7 +232,7 @@ TEST(test_layer, load_1_1_0_header) {

TEST(test_layer, load_1_2_0_preset_and_setting_type) {
Layer layer;
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_reference_1_2_0.json", LAYER_TYPE_EXPLICIT);
const bool load_loaded = layer.Load(":/layers/VK_LAYER_LUNARG_reference_1_2_0.json", Dummy(), LAYER_TYPE_EXPLICIT);
ASSERT_TRUE(load_loaded);

// Preset Enum
Expand Down
Loading

0 comments on commit 4fbbac9

Please sign in to comment.