diff options
author | Juan Linietsky <juan@godotengine.org> | 2021-03-24 20:44:13 -0300 |
---|---|---|
committer | reduz <reduzio@gmail.com> | 2021-04-19 14:12:22 -0300 |
commit | 2b730cad902196e081debfb47c2e3d7ecb472b81 (patch) | |
tree | eb7c7cba55a36012adec07f3846d7e34295980ae /core | |
parent | 29775a1714d01f35570ef708d24a1cde77aa1a5a (diff) |
Use multiple threads to import.
- For now everything imports multithreaded by default (should work I guess, let's test).
- Controllable per importer
Early test benchmark. 64 large textures (importing as lossless, _not_ as vram) on a mobile i7, 12 threads:
Importing goes down from 46 to 7 seconds.
For VRAM I will change the logic to use a compressing thread in a subsequent PR, as well as implementing Betsy.
Diffstat (limited to 'core')
-rw-r--r-- | core/io/resource_importer.cpp | 28 | ||||
-rw-r--r-- | core/io/resource_importer.h | 5 | ||||
-rw-r--r-- | core/templates/thread_work_pool.h | 11 |
3 files changed, 42 insertions, 2 deletions
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index 5ca0eb884a..b503655edd 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -192,6 +192,34 @@ bool ResourceFormatImporter::recognize_path(const String &p_path, const String & return FileAccess::exists(p_path + ".import"); } +Error ResourceFormatImporter::get_import_order_threads_and_importer(const String &p_path, int &r_order, bool &r_can_threads, String &r_importer) const { + r_order = 0; + r_importer = ""; + + r_can_threads = false; + Ref<ResourceImporter> importer; + + if (FileAccess::exists(p_path + ".import")) { + PathAndType pat; + Error err = _get_path_and_type(p_path, pat); + + if (err == OK) { + importer = get_importer_by_name(pat.importer); + } + } else { + importer = get_importer_by_extension(p_path.get_extension().to_lower()); + } + + if (importer.is_valid()) { + r_order = importer->get_import_order(); + r_importer = importer->get_importer_name(); + r_can_threads = importer->can_import_threaded(); + return OK; + } else { + return ERR_INVALID_PARAMETER; + } +} + int ResourceFormatImporter::get_import_order(const String &p_path) const { Ref<ResourceImporter> importer; diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index eeb486073e..a14d6ba52c 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -72,6 +72,8 @@ public: virtual int get_import_order(const String &p_path) const; + Error get_import_order_threads_and_importer(const String &p_path, int &r_order, bool &r_can_threads, String &r_importer) const; + String get_internal_resource_path(const String &p_path) const; void get_internal_resource_path_list(const String &p_path, List<String> *r_paths); @@ -126,6 +128,9 @@ public: virtual String get_option_group_file() const { return String(); } virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) = 0; + virtual bool can_import_threaded() const { return true; } + virtual void import_threaded_begin() {} + virtual void import_threaded_end() {} virtual Error import_group_file(const String &p_group_file, const Map<String, Map<StringName, Variant>> &p_source_file_options, const Map<String, String> &p_base_paths) { return ERR_UNAVAILABLE; } virtual bool are_import_settings_valid(const String &p_path) const { return true; } diff --git a/core/templates/thread_work_pool.h b/core/templates/thread_work_pool.h index 19ab1dda3a..9f7a692cc5 100644 --- a/core/templates/thread_work_pool.h +++ b/core/templates/thread_work_pool.h @@ -83,7 +83,7 @@ public: ERR_FAIL_COND(!threads); //never initialized ERR_FAIL_COND(current_work != nullptr); - index.store(0); + index.store(0, std::memory_order_release); Work<C, M, U> *w = memnew((Work<C, M, U>)); w->instance = p_instance; @@ -104,8 +104,15 @@ public: return current_work != nullptr; } + bool is_done_dispatching() const { + ERR_FAIL_COND_V(current_work == nullptr, false); + return index.load(std::memory_order_acquire) >= current_work->max_elements; + } + uint32_t get_work_index() const { - return index; + ERR_FAIL_COND_V(current_work == nullptr, 0); + uint32_t idx = index.load(std::memory_order_acquire); + return MIN(idx, current_work->max_elements); } void end_work() { |