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;
|
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)});
|
::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
|
// 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());
|
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.
|
const usz num_threads_succeeded = map_workload("PKG Installer "sv, thread_count, [&reader]()
|
||||||
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
reader.extract_worker();
|
reader.extract_worker();
|
||||||
num_threads_succeeded++;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (thread_count != num_threads_succeeded)
|
if (thread_count != num_threads_succeeded)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -120,50 +120,11 @@ namespace rsx
|
|||||||
|
|
||||||
// Parse entries (multithreaded)
|
// Parse entries (multithreaded)
|
||||||
const std::vector<game_enumeration<big_picture_game_entry>::path_entry>& entries = m_game_enumeration.path_entries();
|
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());
|
usz thread_count = std::min<usz>(utils::get_thread_count(), entries.size());
|
||||||
if (thread_count > 1)
|
map_workload("BPM Parser "sv, thread_count, entries.size(), [this, &entries](usz index)
|
||||||
{
|
{
|
||||||
atomic_t<usz> entry_indexer = 0;
|
m_game_enumeration.parse_entry(entries[index]);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to update the app version for disc games if there is a patch
|
// Try to update the app version for disc games if there is a patch
|
||||||
// Also try to find updated game icons and movies
|
// Also try to find updated game icons and movies
|
||||||
@@ -186,11 +147,19 @@ namespace rsx
|
|||||||
return a.name < b.name;
|
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);
|
std::lock_guard lock(m_reload_mutex);
|
||||||
|
|
||||||
@@ -206,7 +175,7 @@ namespace rsx
|
|||||||
|
|
||||||
std::unique_ptr<horizontal_layout> row;
|
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)
|
if (i % m_columns == 0)
|
||||||
{
|
{
|
||||||
@@ -219,8 +188,7 @@ namespace rsx
|
|||||||
row->pack_padding = 20;
|
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(tiles[i]));
|
||||||
m_tiles.push_back(row->add_element(tile));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (row)
|
if (row)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace rsx
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void start_reload();
|
void start_reload();
|
||||||
void finish_reload();
|
void finish_reload(std::vector<std::unique_ptr<big_picture_game_tile>>&& tiles);
|
||||||
void select_tile(s32 index);
|
void select_tile(s32 index);
|
||||||
|
|
||||||
static constexpr u16 m_columns = 5;
|
static constexpr u16 m_columns = 5;
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ u64 memory_viewer_panel::OnSearch(std::string wstr, u32 mode)
|
|||||||
|
|
||||||
vm::writer_lock rlock;
|
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)
|
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;
|
found += local_found;
|
||||||
});
|
});
|
||||||
|
|
||||||
workers.join();
|
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user