mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-10-11 22:49:55 +00:00
big picture mode: Create tiles multithreaded
This commit is contained in:
@@ -4033,3 +4033,81 @@ bool thread_ctrl::is_main()
|
||||
{
|
||||
return get_tid() == utils::main_tid;
|
||||
}
|
||||
|
||||
usz map_workload(std::string_view thread_name, usz thread_count, usz count, std::function<void(usz)>&& func)
|
||||
{
|
||||
ensure(!!func);
|
||||
|
||||
if (thread_count <= 1)
|
||||
{
|
||||
for (usz i = 0; i < count; i++)
|
||||
{
|
||||
func(i);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
atomic_t<u32> num_threads_succeeded {0}; // Check if any thread didn't finish. For example when hitting an exception.
|
||||
|
||||
atomic_t<usz> indexer = 0;
|
||||
const auto iterate = [count, &func, &indexer]()
|
||||
{
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
// Make sure indexer does not exceed count
|
||||
const usz index = indexer.fetch_op([count](usz& v)
|
||||
{
|
||||
if (v < count)
|
||||
{
|
||||
v++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}).first;
|
||||
|
||||
if (index >= count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
func(index);
|
||||
}
|
||||
};
|
||||
named_thread_group workers(thread_name, ::narrow<u32>(thread_count) - 1, [&iterate, &num_threads_succeeded]()
|
||||
{
|
||||
iterate();
|
||||
num_threads_succeeded++;
|
||||
});
|
||||
|
||||
iterate();
|
||||
|
||||
workers.join();
|
||||
|
||||
return num_threads_succeeded + 1;
|
||||
}
|
||||
|
||||
usz map_workload(std::string_view thread_name, usz thread_count, std::function<void()>&& func)
|
||||
{
|
||||
ensure(!!func);
|
||||
|
||||
if (thread_count <= 1)
|
||||
{
|
||||
func();
|
||||
return 1;
|
||||
}
|
||||
|
||||
atomic_t<u32> num_threads_succeeded {0}; // Check if any thread didn't finish. For example when hitting an exception.
|
||||
|
||||
named_thread_group workers(thread_name, ::narrow<u32>(thread_count) - 1, [&func, &num_threads_succeeded]()
|
||||
{
|
||||
func();
|
||||
num_threads_succeeded++;
|
||||
});
|
||||
|
||||
func();
|
||||
|
||||
workers.join();
|
||||
|
||||
return num_threads_succeeded + 1;
|
||||
}
|
||||
|
||||
@@ -905,3 +905,6 @@ public:
|
||||
::operator delete(static_cast<void*>(m_threads), std::align_val_t{alignof(Thread)});
|
||||
}
|
||||
};
|
||||
|
||||
usz map_workload(std::string_view thread_name, usz thread_count, usz count, std::function<void(usz)>&& func);
|
||||
usz map_workload(std::string_view thread_name, usz thread_count, std::function<void()>&& func);
|
||||
|
||||
+2
-18
@@ -1364,26 +1364,10 @@ package_install_result package_reader::extract_data(std::deque<package_reader>&
|
||||
{
|
||||
// Disc archives don't like multithreaded file reads, so let's just use a single thread here
|
||||
const usz thread_count = from_optical_drive ? 1 : std::min<usz>(utils::get_thread_count(), reader.m_install_entries.size());
|
||||
atomic_t<u32> num_threads_succeeded {0}; // Check if any thread didn't finish. For example when hitting an exception.
|
||||
|
||||
if (thread_count > 1)
|
||||
{
|
||||
named_thread_group workers("PKG Installer "sv, ::narrow<u32>(thread_count) - 1, [&]()
|
||||
{
|
||||
reader.extract_worker();
|
||||
num_threads_succeeded++;
|
||||
});
|
||||
|
||||
reader.extract_worker();
|
||||
num_threads_succeeded++;
|
||||
|
||||
workers.join();
|
||||
}
|
||||
else
|
||||
const usz num_threads_succeeded = map_workload("PKG Installer "sv, thread_count, [&reader]()
|
||||
{
|
||||
reader.extract_worker();
|
||||
num_threads_succeeded++;
|
||||
}
|
||||
});
|
||||
|
||||
if (thread_count != num_threads_succeeded)
|
||||
{
|
||||
|
||||
@@ -120,50 +120,11 @@ namespace rsx
|
||||
|
||||
// Parse entries (multithreaded)
|
||||
const std::vector<game_enumeration<big_picture_game_entry>::path_entry>& entries = m_game_enumeration.path_entries();
|
||||
const usz thread_count = std::min<usz>(utils::get_thread_count(), entries.size());
|
||||
if (thread_count > 1)
|
||||
usz thread_count = std::min<usz>(utils::get_thread_count(), entries.size());
|
||||
map_workload("BPM Parser "sv, thread_count, entries.size(), [this, &entries](usz index)
|
||||
{
|
||||
atomic_t<usz> entry_indexer = 0;
|
||||
const auto parse_entries = [this, &entry_indexer, &entries]()
|
||||
{
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
// Make sure entry_indexer does not exceed m_install_entries
|
||||
const usz index = entry_indexer.fetch_op([&entries](usz& v)
|
||||
{
|
||||
if (v < entries.size())
|
||||
{
|
||||
v++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}).first;
|
||||
|
||||
if (index >= entries.size())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
m_game_enumeration.parse_entry(entries[index]);
|
||||
}
|
||||
};
|
||||
named_thread_group workers("BPM Parser "sv, ::narrow<u32>(thread_count) - 1, [&parse_entries]()
|
||||
{
|
||||
parse_entries();
|
||||
});
|
||||
|
||||
parse_entries();
|
||||
|
||||
workers.join();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const game_enumeration<big_picture_game_entry>::path_entry& entry : entries)
|
||||
{
|
||||
m_game_enumeration.parse_entry(entry);
|
||||
}
|
||||
}
|
||||
m_game_enumeration.parse_entry(entries[index]);
|
||||
});
|
||||
|
||||
// Try to update the app version for disc games if there is a patch
|
||||
// Also try to find updated game icons and movies
|
||||
@@ -186,11 +147,19 @@ namespace rsx
|
||||
return a.name < b.name;
|
||||
});
|
||||
|
||||
finish_reload();
|
||||
// Create tiles (multithreaded)
|
||||
std::vector<std::unique_ptr<big_picture_game_tile>> tiles(m_games.size());
|
||||
thread_count = std::min<usz>(utils::get_thread_count(), tiles.size());
|
||||
map_workload("BPM Tiles "sv, thread_count, tiles.size(), [this, &tiles](usz index)
|
||||
{
|
||||
tiles[index] = std::make_unique<big_picture_game_tile>(m_games[index], m_tile_size);
|
||||
});
|
||||
|
||||
finish_reload(std::move(tiles));
|
||||
});
|
||||
}
|
||||
|
||||
void big_picture_game_grid::finish_reload()
|
||||
void big_picture_game_grid::finish_reload(std::vector<std::unique_ptr<big_picture_game_tile>>&& tiles)
|
||||
{
|
||||
std::lock_guard lock(m_reload_mutex);
|
||||
|
||||
@@ -206,7 +175,7 @@ namespace rsx
|
||||
|
||||
std::unique_ptr<horizontal_layout> row;
|
||||
|
||||
for (usz i = 0; i < m_games.size(); i++)
|
||||
for (usz i = 0; i < tiles.size(); i++)
|
||||
{
|
||||
if (i % m_columns == 0)
|
||||
{
|
||||
@@ -219,8 +188,7 @@ namespace rsx
|
||||
row->pack_padding = 20;
|
||||
}
|
||||
|
||||
auto tile = std::make_unique<big_picture_game_tile>(m_games[i], m_tile_size);
|
||||
m_tiles.push_back(row->add_element(tile));
|
||||
m_tiles.push_back(row->add_element(tiles[i]));
|
||||
}
|
||||
|
||||
if (row)
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace rsx
|
||||
|
||||
private:
|
||||
void start_reload();
|
||||
void finish_reload();
|
||||
void finish_reload(std::vector<std::unique_ptr<big_picture_game_tile>>&& tiles);
|
||||
void select_tile(s32 index);
|
||||
|
||||
static constexpr u16 m_columns = 5;
|
||||
|
||||
@@ -185,7 +185,7 @@ u64 memory_viewer_panel::OnSearch(std::string wstr, u32 mode)
|
||||
|
||||
vm::writer_lock rlock;
|
||||
|
||||
const named_thread_group workers("Memory Searcher "sv, max_threads, [&]()
|
||||
map_workload("Memory Searcher "sv, max_threads, [&]()
|
||||
{
|
||||
if (mode == as_inst || mode == as_fake_spu_inst || mode == as_regex_inst || mode == as_regex_fake_spu_inst)
|
||||
{
|
||||
@@ -448,7 +448,5 @@ u64 memory_viewer_panel::OnSearch(std::string wstr, u32 mode)
|
||||
found += local_found;
|
||||
});
|
||||
|
||||
workers.join();
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user