1
0
mirror of https://github.com/godotengine/godot.git synced 2025-12-02 16:48:55 +00:00

Add support for delta encoding to patch PCKs

This commit is contained in:
Mikael Hermansson
2025-10-24 16:10:45 +02:00
parent 9dd6c4dbac
commit 0cc88f34da
17 changed files with 851 additions and 92 deletions

View File

@@ -51,11 +51,14 @@
#include "scene/gui/option_button.h"
#include "scene/gui/popup_menu.h"
#include "scene/gui/rich_text_label.h"
#include "scene/gui/spin_box.h"
#include "scene/gui/split_container.h"
#include "scene/gui/tab_container.h"
#include "scene/gui/texture_rect.h"
#include "scene/gui/tree.h"
#include <zstd.h>
void ProjectExportTextureFormatError::_on_fix_texture_format_pressed() {
export_dialog->hide();
ProjectSettingsEditor *project_settings = EditorNode::get_singleton()->get_project_settings();
@@ -301,6 +304,19 @@ void ProjectExportDialog::_edit_preset(int p_index) {
exclude_filters->set_text(current->get_exclude_filter());
server_strip_message->set_visible(current->get_export_filter() == EditorExportPreset::EXPORT_CUSTOMIZED);
bool patch_delta_encoding_enabled = current->is_patch_delta_encoding_enabled();
patch_delta_encoding->set_pressed(patch_delta_encoding_enabled);
patch_delta_zstd_level->set_editable(patch_delta_encoding_enabled);
patch_delta_zstd_level->set_value(current->get_patch_delta_zstd_level());
patch_delta_min_reduction->set_editable(patch_delta_encoding_enabled);
patch_delta_min_reduction->set_value(current->get_patch_delta_min_reduction() * 100);
patch_delta_include_filter->set_editable(patch_delta_encoding_enabled);
patch_delta_exclude_filter->set_editable(patch_delta_encoding_enabled);
if (!updating_patch_delta_filters) {
patch_delta_include_filter->set_text(current->get_patch_delta_include_filter());
patch_delta_exclude_filter->set_text(current->get_patch_delta_exclude_filter());
}
patches->clear();
TreeItem *patch_root = patches->create_item();
Vector<String> patch_list = current->get_patches();
@@ -745,6 +761,11 @@ void ProjectExportDialog::_duplicate_preset() {
preset->set_include_filter(current->get_include_filter());
preset->set_exclude_filter(current->get_exclude_filter());
preset->set_patches(current->get_patches());
preset->set_patch_delta_encoding_enabled(current->is_patch_delta_encoding_enabled());
preset->set_patch_delta_zstd_level(current->get_patch_delta_zstd_level());
preset->set_patch_delta_min_reduction(current->get_patch_delta_min_reduction());
preset->set_patch_delta_include_filter(current->get_patch_delta_include_filter());
preset->set_patch_delta_exclude_filter(current->get_patch_delta_exclude_filter());
preset->set_custom_features(current->get_custom_features());
preset->set_enc_in_filter(current->get_enc_in_filter());
preset->set_enc_ex_filter(current->get_enc_ex_filter());
@@ -1201,6 +1222,75 @@ void ProjectExportDialog::_set_file_export_mode(int p_id) {
_propagate_file_export_mode(include_files->get_root(), EditorExportPreset::MODE_FILE_NOT_CUSTOMIZED);
}
void ProjectExportDialog::_patch_delta_encoding_changed(bool p_pressed) {
if (updating) {
return;
}
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
current->set_patch_delta_encoding_enabled(p_pressed);
_update_current_preset();
}
void ProjectExportDialog::_patch_delta_include_filter_changed(const String &p_filter) {
if (updating) {
return;
}
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
current->set_patch_delta_include_filter(patch_delta_include_filter->get_text());
updating_patch_delta_filters = true;
_update_current_preset();
updating_patch_delta_filters = false;
}
void ProjectExportDialog::_patch_delta_exclude_filter_changed(const String &p_filter) {
if (updating) {
return;
}
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
current->set_patch_delta_exclude_filter(patch_delta_exclude_filter->get_text());
updating_patch_delta_filters = true;
_update_current_preset();
updating_patch_delta_filters = false;
}
void ProjectExportDialog::_patch_delta_zstd_level_changed(double p_value) {
if (updating) {
return;
}
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
current->set_patch_delta_zstd_level((int)p_value);
_update_current_preset();
}
void ProjectExportDialog::_patch_delta_min_reduction_changed(double p_value) {
if (updating) {
return;
}
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
current->set_patch_delta_min_reduction(p_value / 100.0);
_update_current_preset();
}
void ProjectExportDialog::_patch_tree_button_clicked(Object *p_item, int p_column, int p_id, int p_mouse_button_index) {
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
@@ -1657,11 +1747,52 @@ ProjectExportDialog::ProjectExportDialog() {
exclude_filters);
exclude_filters->connect(SceneStringName(text_changed), callable_mp(this, &ProjectExportDialog::_filter_changed));
// Patch packages.
// Patching.
VBoxContainer *patch_vb = memnew(VBoxContainer);
sections->add_child(patch_vb);
patch_vb->set_name(TTR("Patches"));
patch_vb->set_name(TTRC("Patching"));
patch_delta_encoding = memnew(CheckButton);
patch_delta_encoding->connect(SceneStringName(toggled), callable_mp(this, &ProjectExportDialog::_patch_delta_encoding_changed));
patch_delta_encoding->set_text(TTRC("Enable Delta Encoding"));
patch_delta_encoding->set_tooltip_text(TTRC("If checked, any change to a file already present in the base packs will be exported as the difference between the old file and the new file.\n"
"Enabling this comes at the cost of longer export times as well as longer load times for patched resources."));
patch_vb->add_child(patch_delta_encoding);
patch_delta_zstd_level = memnew(SpinBox);
patch_delta_zstd_level->set_min(ZSTD_minCLevel());
patch_delta_zstd_level->set_max(ZSTD_maxCLevel());
patch_delta_zstd_level->set_step(1);
patch_delta_zstd_level->set_tooltip_text(
vformat(TTR("The Zstandard compression level to use when generating delta-encoded patches.\n"
"Higher positive levels will reduce patch sizes, at the cost of longer export time, but do not affect the time it takes to apply patches.\n"
"Negative levels will reduce the time it takes to apply patches, at the cost of worse compression.\n"
"Levels above 19 require more memory both during export and when applying patches, usually for very little benefit.\n"
"Level 0 will cause Zstandard to use its default compression level, which is currently level %d."),
ZSTD_CLEVEL_DEFAULT));
patch_delta_zstd_level->connect(SceneStringName(value_changed), callable_mp(this, &ProjectExportDialog::_patch_delta_zstd_level_changed));
patch_vb->add_margin_child(TTRC("Delta Encoding Compression Level"), patch_delta_zstd_level);
patch_delta_min_reduction = memnew(SpinBox);
patch_delta_min_reduction->set_min(0.0);
patch_delta_min_reduction->set_max(100.0);
patch_delta_min_reduction->set_step(1.0);
patch_delta_min_reduction->set_suffix("%");
patch_delta_min_reduction->set_tooltip_text(TTRC("How much smaller, when compared to the new file, a delta-encoded patch needs to be for it to be exported.\n"
"If the patch is not at least this much smaller, the new file will be exported as-is."));
patch_delta_min_reduction->connect(SceneStringName(value_changed), callable_mp(this, &ProjectExportDialog::_patch_delta_min_reduction_changed));
patch_vb->add_margin_child(TTRC("Delta Encoding Minimum Size Reduction"), patch_delta_min_reduction);
patch_delta_include_filter = memnew(LineEdit);
patch_delta_include_filter->set_accessibility_name(TTRC("Delta Encoding Include Filters"));
patch_delta_include_filter->connect(SceneStringName(text_changed), callable_mp(this, &ProjectExportDialog::_patch_delta_include_filter_changed));
patch_vb->add_margin_child(TTRC("Filters to include files/folders from being delta-encoded\n(comma-separated, e.g: *.gdc, scripts/*)"), patch_delta_include_filter);
patch_delta_exclude_filter = memnew(LineEdit);
patch_delta_exclude_filter->set_accessibility_name(TTRC("Delta Encoding Exclude Filters"));
patch_delta_exclude_filter->connect(SceneStringName(text_changed), callable_mp(this, &ProjectExportDialog::_patch_delta_exclude_filter_changed));
patch_vb->add_margin_child(TTRC("Filters to exclude files/folders from being delta-encoded\n(comma-separated, e.g: *.ctex, textures/*)"), patch_delta_exclude_filter);
patches = memnew(Tree);
patches->set_v_size_flags(Control::SIZE_EXPAND_FILL);