Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fe0f272168 | |||
| b55b44e36f | |||
| 267e9a02b3 | |||
| 97452b9558 | |||
| 0ee2185c59 | |||
| 4fbec776d6 | |||
| 0394e4bb8e | |||
| 39cd6306e6 | |||
| 403fc86c11 | |||
| c317504b5f | |||
| 5aae61775f | |||
| bea7824bd1 | |||
| 7bb2dd75cd | |||
| 899fdb9c44 | |||
| f84328934f | |||
| 8fad7dc248 | |||
| 5b2fa8dd41 | |||
| b869439969 | |||
| 158a693111 | |||
| 1d829150ee | |||
| 01f79d638f | |||
| d418af157a | |||
| e209fff374 | |||
| 4a77ceb151 | |||
| 71e19153ef | |||
| 6c0d902373 | |||
| 427bf76e62 | |||
| b848cc5c3f | |||
| afee2bc8fa | |||
| 21ed944ff9 | |||
| ae3e51c795 | |||
| 2f5808b7ff | |||
| 282bdfd1bf | |||
| d8467ca6c0 | |||
| fadcee14f8 | |||
| 219d0ba978 | |||
| 3a33519598 | |||
| 579f4ea4bd | |||
| 5daf3abe65 | |||
| 36d45b4a7f | |||
| 6f1c6e6ba9 | |||
| c3784b2a08 | |||
| 596323f89f | |||
| 8bd5742349 | |||
| b9251155f8 | |||
| 4ce0a650d1 | |||
| 91341b421d | |||
| 9ad6c26821 | |||
| 3fc7aceea7 | |||
| e29f3b87f1 | |||
| d09e618bd2 | |||
| e55affe264 | |||
| 5fbfc4c19e | |||
| 6f35fb8d26 | |||
| 7cd43b139a | |||
| 3e07655b1b | |||
| 24049591f6 | |||
| 1ea8073783 | |||
| 22162f906b | |||
| ab808fe7cf | |||
| 7f737b022a | |||
| 4bc3c788f5 |
@@ -1,6 +1,9 @@
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
stages:
|
||||
- stage: merge
|
||||
displayName: 'merge'
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
stages:
|
||||
- stage: merge
|
||||
displayName: 'merge'
|
||||
|
||||
+5
-5
@@ -237,7 +237,7 @@ yuzu_find_packages()
|
||||
|
||||
# Qt5 requires that we find components, so it doesn't fit our pretty little find package function
|
||||
if(ENABLE_QT)
|
||||
set(QT_VERSION 5.12)
|
||||
set(QT_VERSION 5.15)
|
||||
# We want to load the generated conan qt config so that we get the QT_ROOT var so that we can use the official
|
||||
# Qt5Config inside the root folder instead of the conan generated one.
|
||||
if(EXISTS ${CMAKE_BINARY_DIR}/qtConfig.cmake)
|
||||
@@ -339,8 +339,8 @@ if(ENABLE_QT)
|
||||
set(QT_PREFIX_HINT)
|
||||
|
||||
if(YUZU_USE_BUNDLED_QT)
|
||||
if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64)
|
||||
set(QT_BUILD qt-5.12.8-msvc2017_64)
|
||||
if ((MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) AND ARCHITECTURE_x86_64)
|
||||
set(QT_BUILD qt-5.15.2-msvc2019_64)
|
||||
elseif ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux") AND NOT MINGW AND ARCHITECTURE_x86_64)
|
||||
set(QT_BUILD qt5_5_15_2)
|
||||
else()
|
||||
@@ -369,7 +369,7 @@ endif()
|
||||
if (ENABLE_SDL2)
|
||||
if (YUZU_USE_BUNDLED_SDL2)
|
||||
# Detect toolchain and platform
|
||||
if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64)
|
||||
if ((MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) AND ARCHITECTURE_x86_64)
|
||||
set(SDL2_VER "SDL2-2.0.16")
|
||||
else()
|
||||
message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable YUZU_USE_BUNDLED_SDL2 and provide your own.")
|
||||
@@ -462,7 +462,7 @@ if (CONAN_REQUIRED_LIBS)
|
||||
if(ENABLE_QT)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CONAN_QT_ROOT_RELEASE}")
|
||||
list(APPEND CMAKE_PREFIX_PATH "${CONAN_QT_ROOT_RELEASE}")
|
||||
find_package(Qt5 5.12 REQUIRED COMPONENTS Widgets)
|
||||
find_package(Qt5 5.15 REQUIRED COMPONENTS Widgets)
|
||||
if (YUZU_USE_QT_WEB_ENGINE)
|
||||
find_package(Qt5 REQUIRED COMPONENTS WebEngineCore WebEngineWidgets)
|
||||
endif()
|
||||
|
||||
@@ -33,6 +33,7 @@ function(copy_yuzu_Qt5_deps target_dir)
|
||||
Qt5Positioning$<$<CONFIG:Debug>:d>.*
|
||||
Qt5PrintSupport$<$<CONFIG:Debug>:d>.*
|
||||
Qt5Qml$<$<CONFIG:Debug>:d>.*
|
||||
Qt5QmlModels$<$<CONFIG:Debug>:d>.*
|
||||
Qt5Quick$<$<CONFIG:Debug>:d>.*
|
||||
Qt5QuickWidgets$<$<CONFIG:Debug>:d>.*
|
||||
Qt5WebChannel$<$<CONFIG:Debug>:d>.*
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <numbers>
|
||||
|
||||
#include "audio_core/algorithm/interpolate.h"
|
||||
#include "audio_core/command_generator.h"
|
||||
#include "audio_core/effect_context.h"
|
||||
#include "audio_core/mix_context.h"
|
||||
#include "audio_core/voice_context.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "audio_core/behavior_info.h"
|
||||
#include "audio_core/common.h"
|
||||
#include "audio_core/effect_context.h"
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "audio_core/behavior_info.h"
|
||||
#include "audio_core/voice_context.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
@@ -79,6 +79,7 @@ add_library(common STATIC
|
||||
logging/filter.cpp
|
||||
logging/filter.h
|
||||
logging/log.h
|
||||
logging/log_entry.h
|
||||
logging/text_formatter.cpp
|
||||
logging/text_formatter.h
|
||||
logging/types.h
|
||||
|
||||
@@ -314,8 +314,8 @@ private:
|
||||
}
|
||||
|
||||
void UntrackPlaceholder(boost::icl::separate_interval_set<size_t>::iterator it) {
|
||||
placeholders.erase(it);
|
||||
placeholder_host_pointers.erase(it->lower());
|
||||
placeholders.erase(it);
|
||||
}
|
||||
|
||||
/// Return true when a given memory region is a "nieche" and the placeholders don't have to be
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h> // For OutputDebugStringW
|
||||
#endif
|
||||
@@ -22,6 +24,7 @@
|
||||
|
||||
#include "common/logging/backend.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/logging/log_entry.h"
|
||||
#include "common/logging/text_formatter.h"
|
||||
#include "common/settings.h"
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <algorithm>
|
||||
#include <string_view>
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include "common/logging/types.h"
|
||||
|
||||
namespace Common::Log {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "common/logging/types.h"
|
||||
|
||||
namespace Common::Log {
|
||||
|
||||
/**
|
||||
* A log entry. Log entries are store in a structured format to permit more varied output
|
||||
* formatting on different frontends, as well as facilitating filtering and aggregation.
|
||||
*/
|
||||
struct Entry {
|
||||
std::chrono::microseconds timestamp;
|
||||
Class log_class{};
|
||||
Level log_level{};
|
||||
const char* filename = nullptr;
|
||||
unsigned int line_num = 0;
|
||||
std::string function;
|
||||
std::string message;
|
||||
bool final_entry = false;
|
||||
};
|
||||
|
||||
} // namespace Common::Log
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/logging/filter.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/logging/log_entry.h"
|
||||
#include "common/logging/text_formatter.h"
|
||||
#include "common/string_util.h"
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Common::Log {
|
||||
@@ -131,19 +129,4 @@ enum class Class : u8 {
|
||||
Count ///< Total number of logging classes
|
||||
};
|
||||
|
||||
/**
|
||||
* A log entry. Log entries are store in a structured format to permit more varied output
|
||||
* formatting on different frontends, as well as facilitating filtering and aggregation.
|
||||
*/
|
||||
struct Entry {
|
||||
std::chrono::microseconds timestamp;
|
||||
Class log_class{};
|
||||
Level log_level{};
|
||||
const char* filename = nullptr;
|
||||
unsigned int line_num = 0;
|
||||
std::string function;
|
||||
std::string message;
|
||||
bool final_entry = false;
|
||||
};
|
||||
|
||||
} // namespace Common::Log
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <array>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -519,6 +519,9 @@ struct Values {
|
||||
|
||||
BasicSetting<bool> mouse_panning{false, "mouse_panning"};
|
||||
BasicRangedSetting<u8> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"};
|
||||
BasicSetting<bool> mouse_as_joystick{false, "mouse_as_joystick"};
|
||||
BasicRangedSetting<u16> max_mouse_movement{500, 0, 65535, "max_mouse_movement"};
|
||||
BasicRangedSetting<u8> mouse_as_joystick_deadzone{20, 1, 100, "mouse_as_joystick_deadzone"};
|
||||
BasicSetting<bool> mouse_enabled{false, "mouse_enabled"};
|
||||
std::string mouse_device;
|
||||
MouseButtonsRaw mouse_buttons;
|
||||
|
||||
@@ -216,6 +216,7 @@ add_library(core STATIC
|
||||
hle/kernel/k_session.h
|
||||
hle/kernel/k_shared_memory.cpp
|
||||
hle/kernel/k_shared_memory.h
|
||||
hle/kernel/k_shared_memory_info.h
|
||||
hle/kernel/k_slab_heap.h
|
||||
hle/kernel/k_spin_lock.cpp
|
||||
hle/kernel/k_spin_lock.h
|
||||
|
||||
@@ -421,6 +421,7 @@ struct System::Impl {
|
||||
bool is_async_gpu{};
|
||||
|
||||
ExecuteProgramCallback execute_program_callback;
|
||||
ExitCallback exit_callback;
|
||||
|
||||
std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
|
||||
std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_dynarmic{};
|
||||
@@ -798,6 +799,18 @@ void System::ExecuteProgram(std::size_t program_index) {
|
||||
}
|
||||
}
|
||||
|
||||
void System::RegisterExitCallback(ExitCallback&& callback) {
|
||||
impl->exit_callback = std::move(callback);
|
||||
}
|
||||
|
||||
void System::Exit() {
|
||||
if (impl->exit_callback) {
|
||||
impl->exit_callback();
|
||||
} else {
|
||||
LOG_CRITICAL(Core, "exit_callback must be initialized by the frontend");
|
||||
}
|
||||
}
|
||||
|
||||
void System::ApplySettings() {
|
||||
if (IsPoweredOn()) {
|
||||
Renderer().RefreshBaseSettings();
|
||||
|
||||
@@ -387,6 +387,18 @@ public:
|
||||
*/
|
||||
void ExecuteProgram(std::size_t program_index);
|
||||
|
||||
/// Type used for the frontend to designate a callback for System to exit the application.
|
||||
using ExitCallback = std::function<void()>;
|
||||
|
||||
/**
|
||||
* Registers a callback from the frontend for System to exit the application.
|
||||
* @param callback Callback from the frontend to exit the application.
|
||||
*/
|
||||
void RegisterExitCallback(ExitCallback&& callback);
|
||||
|
||||
/// Instructs the frontend to exit the application.
|
||||
void Exit();
|
||||
|
||||
/// Applies any changes to settings to this core instance.
|
||||
void ApplySettings();
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ void ProgramMetadata::LoadManual(bool is_64_bit, ProgramAddressSpaceType address
|
||||
aci_header.title_id = title_id;
|
||||
aci_file_access.permissions = filesystem_permissions;
|
||||
npdm_header.system_resource_size = system_resource_size;
|
||||
aci_kernel_capabilities = std ::move(capabilities);
|
||||
aci_kernel_capabilities = std::move(capabilities);
|
||||
}
|
||||
|
||||
bool ProgramMetadata::Is64BitProgram() const {
|
||||
|
||||
@@ -4,17 +4,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/ipc.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/kernel/k_client_port.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/k_resource_limit.h"
|
||||
#include "core/hle/kernel/k_session.h"
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/kernel/k_auto_object.h"
|
||||
#include "core/hle/kernel/k_handle_table.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "common/concepts.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/hle/ipc.h"
|
||||
#include "core/hle/kernel/k_auto_object.h"
|
||||
#include "core/hle/kernel/svc_common.h"
|
||||
|
||||
union ResultCode;
|
||||
@@ -38,6 +37,7 @@ namespace Kernel {
|
||||
|
||||
class Domain;
|
||||
class HLERequestContext;
|
||||
class KAutoObject;
|
||||
class KernelCore;
|
||||
class KHandleTable;
|
||||
class KProcess;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "core/hle/kernel/k_auto_object_container.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
namespace Kernel {
|
||||
|
||||
KHandleTable::KHandleTable(KernelCore& kernel_) : kernel{kernel_} {}
|
||||
KHandleTable ::~KHandleTable() = default;
|
||||
KHandleTable::~KHandleTable() = default;
|
||||
|
||||
ResultCode KHandleTable::Finalize() {
|
||||
// Get the table and clear our record of it.
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "core/hle/kernel/k_scheduler.h"
|
||||
#include "core/hle/kernel/k_scoped_resource_reservation.h"
|
||||
#include "core/hle/kernel/k_shared_memory.h"
|
||||
#include "core/hle/kernel/k_shared_memory_info.h"
|
||||
#include "core/hle/kernel/k_slab_heap.h"
|
||||
#include "core/hle/kernel/k_thread.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
@@ -254,10 +255,26 @@ ResultCode KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAdd
|
||||
// Lock ourselves, to prevent concurrent access.
|
||||
KScopedLightLock lk(state_lock);
|
||||
|
||||
// TODO(bunnei): Manage KSharedMemoryInfo list here.
|
||||
// Try to find an existing info for the memory.
|
||||
KSharedMemoryInfo* shemen_info = nullptr;
|
||||
const auto iter = std::find_if(
|
||||
shared_memory_list.begin(), shared_memory_list.end(),
|
||||
[shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; });
|
||||
if (iter != shared_memory_list.end()) {
|
||||
shemen_info = *iter;
|
||||
}
|
||||
|
||||
// Open a reference to the shared memory.
|
||||
if (shemen_info == nullptr) {
|
||||
shemen_info = KSharedMemoryInfo::Allocate(kernel);
|
||||
R_UNLESS(shemen_info != nullptr, ResultOutOfMemory);
|
||||
|
||||
shemen_info->Initialize(shmem);
|
||||
shared_memory_list.push_back(shemen_info);
|
||||
}
|
||||
|
||||
// Open a reference to the shared memory and its info.
|
||||
shmem->Open();
|
||||
shemen_info->Open();
|
||||
|
||||
return ResultSuccess;
|
||||
}
|
||||
@@ -267,7 +284,20 @@ void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr a
|
||||
// Lock ourselves, to prevent concurrent access.
|
||||
KScopedLightLock lk(state_lock);
|
||||
|
||||
// TODO(bunnei): Manage KSharedMemoryInfo list here.
|
||||
KSharedMemoryInfo* shemen_info = nullptr;
|
||||
const auto iter = std::find_if(
|
||||
shared_memory_list.begin(), shared_memory_list.end(),
|
||||
[shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; });
|
||||
if (iter != shared_memory_list.end()) {
|
||||
shemen_info = *iter;
|
||||
}
|
||||
|
||||
ASSERT(shemen_info != nullptr);
|
||||
|
||||
if (shemen_info->Close()) {
|
||||
shared_memory_list.erase(iter);
|
||||
KSharedMemoryInfo::Free(kernel, shemen_info);
|
||||
}
|
||||
|
||||
// Close a reference to the shared memory.
|
||||
shmem->Close();
|
||||
@@ -412,6 +442,24 @@ void KProcess::Finalize() {
|
||||
// Finalize the handle table and close any open handles.
|
||||
handle_table.Finalize();
|
||||
|
||||
// Free all shared memory infos.
|
||||
{
|
||||
auto it = shared_memory_list.begin();
|
||||
while (it != shared_memory_list.end()) {
|
||||
KSharedMemoryInfo* info = *it;
|
||||
KSharedMemory* shmem = info->GetSharedMemory();
|
||||
|
||||
while (!info->Close()) {
|
||||
shmem->Close();
|
||||
}
|
||||
|
||||
shmem->Close();
|
||||
|
||||
it = shared_memory_list.erase(it);
|
||||
KSharedMemoryInfo::Free(kernel, info);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform inherited finalization.
|
||||
KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize();
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ class KernelCore;
|
||||
class KPageTable;
|
||||
class KResourceLimit;
|
||||
class KThread;
|
||||
class KSharedMemoryInfo;
|
||||
class TLSPage;
|
||||
|
||||
struct CodeSet;
|
||||
@@ -448,6 +449,9 @@ private:
|
||||
/// List of threads that are running with this process as their owner.
|
||||
std::list<const KThread*> thread_list;
|
||||
|
||||
/// List of shared memory that are running with this process as their owner.
|
||||
std::list<KSharedMemoryInfo*> shared_memory_list;
|
||||
|
||||
/// Address of the top of the main thread's stack
|
||||
VAddr main_thread_stack_top{};
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <boost/intrusive/list.hpp>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "core/hle/kernel/slab_helpers.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
class KSharedMemory;
|
||||
|
||||
class KSharedMemoryInfo final : public KSlabAllocated<KSharedMemoryInfo>,
|
||||
public boost::intrusive::list_base_hook<> {
|
||||
|
||||
public:
|
||||
explicit KSharedMemoryInfo() = default;
|
||||
|
||||
constexpr void Initialize(KSharedMemory* shmem) {
|
||||
shared_memory = shmem;
|
||||
}
|
||||
|
||||
constexpr KSharedMemory* GetSharedMemory() const {
|
||||
return shared_memory;
|
||||
}
|
||||
|
||||
constexpr void Open() {
|
||||
++reference_count;
|
||||
}
|
||||
|
||||
constexpr bool Close() {
|
||||
return (--reference_count) == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
KSharedMemory* shared_memory{};
|
||||
size_t reference_count{};
|
||||
};
|
||||
|
||||
} // namespace Kernel
|
||||
@@ -49,6 +49,7 @@ class KScheduler;
|
||||
class KServerSession;
|
||||
class KSession;
|
||||
class KSharedMemory;
|
||||
class KSharedMemoryInfo;
|
||||
class KThread;
|
||||
class KTransferMemory;
|
||||
class KWritableEvent;
|
||||
@@ -309,6 +310,8 @@ public:
|
||||
return slab_heap_container->session;
|
||||
} else if constexpr (std::is_same_v<T, KSharedMemory>) {
|
||||
return slab_heap_container->shared_memory;
|
||||
} else if constexpr (std::is_same_v<T, KSharedMemoryInfo>) {
|
||||
return slab_heap_container->shared_memory_info;
|
||||
} else if constexpr (std::is_same_v<T, KThread>) {
|
||||
return slab_heap_container->thread;
|
||||
} else if constexpr (std::is_same_v<T, KTransferMemory>) {
|
||||
@@ -362,6 +365,7 @@ private:
|
||||
KSlabHeap<KResourceLimit> resource_limit;
|
||||
KSlabHeap<KSession> session;
|
||||
KSlabHeap<KSharedMemory> shared_memory;
|
||||
KSlabHeap<KSharedMemoryInfo> shared_memory_info;
|
||||
KSlabHeap<KThread> thread;
|
||||
KSlabHeap<KTransferMemory> transfer_memory;
|
||||
KSlabHeap<KWritableEvent> writeable_event;
|
||||
|
||||
@@ -320,17 +320,19 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
|
||||
KScopedAutoObject session =
|
||||
kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
|
||||
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
|
||||
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
|
||||
|
||||
auto thread = kernel.CurrentScheduler()->GetCurrentThread();
|
||||
{
|
||||
KScopedSchedulerLock lock(kernel);
|
||||
thread->SetState(ThreadState::Waiting);
|
||||
thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
|
||||
session->SendSyncRequest(thread, system.Memory(), system.CoreTiming());
|
||||
|
||||
{
|
||||
KScopedAutoObject session =
|
||||
kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
|
||||
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
|
||||
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
|
||||
session->SendSyncRequest(thread, system.Memory(), system.CoreTiming());
|
||||
}
|
||||
}
|
||||
|
||||
KSynchronizationObject* dummy{};
|
||||
|
||||
@@ -4,15 +4,12 @@
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/acc/async_context.h"
|
||||
|
||||
namespace Service::Account {
|
||||
IAsyncContext::IAsyncContext(Core::System& system_)
|
||||
: ServiceFramework{system_, "IAsyncContext"}, compeletion_event{system_.Kernel()} {
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(compeletion_event));
|
||||
compeletion_event.Initialize("IAsyncContext:CompletionEvent");
|
||||
|
||||
: ServiceFramework{system_, "IAsyncContext"}, service_context{system_, "IAsyncContext"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IAsyncContext::GetSystemEvent, "GetSystemEvent"},
|
||||
@@ -23,6 +20,12 @@ IAsyncContext::IAsyncContext(Core::System& system_)
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
completion_event = service_context.CreateEvent("IAsyncContext:CompletionEvent");
|
||||
}
|
||||
|
||||
IAsyncContext::~IAsyncContext() {
|
||||
service_context.CloseEvent(completion_event);
|
||||
}
|
||||
|
||||
void IAsyncContext::GetSystemEvent(Kernel::HLERequestContext& ctx) {
|
||||
@@ -30,7 +33,7 @@ void IAsyncContext::GetSystemEvent(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(compeletion_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(completion_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void IAsyncContext::Cancel(Kernel::HLERequestContext& ctx) {
|
||||
@@ -62,7 +65,7 @@ void IAsyncContext::GetResult(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
void IAsyncContext::MarkComplete() {
|
||||
is_complete.store(true);
|
||||
compeletion_event.GetWritableEvent().Signal();
|
||||
completion_event->GetWritableEvent().Signal();
|
||||
}
|
||||
|
||||
} // namespace Service::Account
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
@@ -17,6 +17,7 @@ namespace Service::Account {
|
||||
class IAsyncContext : public ServiceFramework<IAsyncContext> {
|
||||
public:
|
||||
explicit IAsyncContext(Core::System& system_);
|
||||
~IAsyncContext() override;
|
||||
|
||||
void GetSystemEvent(Kernel::HLERequestContext& ctx);
|
||||
void Cancel(Kernel::HLERequestContext& ctx);
|
||||
@@ -30,8 +31,10 @@ protected:
|
||||
|
||||
void MarkComplete();
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
std::atomic<bool> is_complete{false};
|
||||
Kernel::KEvent compeletion_event;
|
||||
Kernel::KEvent* completion_event;
|
||||
};
|
||||
|
||||
} // namespace Service::Account
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/k_transfer_memory.h"
|
||||
#include "core/hle/kernel/k_writable_event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/acc/profile_manager.h"
|
||||
#include "core/hle/service/am/am.h"
|
||||
@@ -254,8 +252,9 @@ IDebugFunctions::IDebugFunctions(Core::System& system_)
|
||||
IDebugFunctions::~IDebugFunctions() = default;
|
||||
|
||||
ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nvflinger_)
|
||||
: ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_},
|
||||
launchable_event{system.Kernel()}, accumulated_suspended_tick_changed_event{system.Kernel()} {
|
||||
: ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_}, service_context{
|
||||
system,
|
||||
"ISelfController"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ISelfController::Exit, "Exit"},
|
||||
@@ -311,9 +310,7 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(launchable_event));
|
||||
|
||||
launchable_event.Initialize("ISelfController:LaunchableEvent");
|
||||
launchable_event = service_context.CreateEvent("ISelfController:LaunchableEvent");
|
||||
|
||||
// This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is
|
||||
// called. Yuzu can just create it unconditionally, since it doesn't need to support multiple
|
||||
@@ -321,21 +318,23 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
|
||||
// suspended if the event has previously been created by a call to
|
||||
// GetAccumulatedSuspendedTickChangedEvent.
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(accumulated_suspended_tick_changed_event));
|
||||
accumulated_suspended_tick_changed_event.Initialize(
|
||||
"ISelfController:AccumulatedSuspendedTickChangedEvent");
|
||||
accumulated_suspended_tick_changed_event.GetWritableEvent().Signal();
|
||||
accumulated_suspended_tick_changed_event =
|
||||
service_context.CreateEvent("ISelfController:AccumulatedSuspendedTickChangedEvent");
|
||||
accumulated_suspended_tick_changed_event->GetWritableEvent().Signal();
|
||||
}
|
||||
|
||||
ISelfController::~ISelfController() = default;
|
||||
ISelfController::~ISelfController() {
|
||||
service_context.CloseEvent(launchable_event);
|
||||
service_context.CloseEvent(accumulated_suspended_tick_changed_event);
|
||||
}
|
||||
|
||||
void ISelfController::Exit(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
system.Shutdown();
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
|
||||
system.Exit();
|
||||
}
|
||||
|
||||
void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
|
||||
@@ -383,11 +382,11 @@ void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) {
|
||||
void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
|
||||
launchable_event.GetWritableEvent().Signal();
|
||||
launchable_event->GetWritableEvent().Signal();
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(launchable_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(launchable_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) {
|
||||
@@ -566,7 +565,7 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(accumulated_suspended_tick_changed_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(accumulated_suspended_tick_changed_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestContext& ctx) {
|
||||
@@ -584,40 +583,39 @@ void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestCo
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel)
|
||||
: on_new_message{kernel}, on_operation_mode_changed{kernel} {
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(on_new_message));
|
||||
Kernel::KAutoObject::Create(std::addressof(on_operation_mode_changed));
|
||||
|
||||
on_new_message.Initialize("AMMessageQueue:OnMessageReceived");
|
||||
on_operation_mode_changed.Initialize("AMMessageQueue:OperationModeChanged");
|
||||
AppletMessageQueue::AppletMessageQueue(Core::System& system)
|
||||
: service_context{system, "AppletMessageQueue"} {
|
||||
on_new_message = service_context.CreateEvent("AMMessageQueue:OnMessageReceived");
|
||||
on_operation_mode_changed = service_context.CreateEvent("AMMessageQueue:OperationModeChanged");
|
||||
}
|
||||
|
||||
AppletMessageQueue::~AppletMessageQueue() = default;
|
||||
AppletMessageQueue::~AppletMessageQueue() {
|
||||
service_context.CloseEvent(on_new_message);
|
||||
service_context.CloseEvent(on_operation_mode_changed);
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent& AppletMessageQueue::GetMessageReceiveEvent() {
|
||||
return on_new_message.GetReadableEvent();
|
||||
return on_new_message->GetReadableEvent();
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent& AppletMessageQueue::GetOperationModeChangedEvent() {
|
||||
return on_operation_mode_changed.GetReadableEvent();
|
||||
return on_operation_mode_changed->GetReadableEvent();
|
||||
}
|
||||
|
||||
void AppletMessageQueue::PushMessage(AppletMessage msg) {
|
||||
messages.push(msg);
|
||||
on_new_message.GetWritableEvent().Signal();
|
||||
on_new_message->GetWritableEvent().Signal();
|
||||
}
|
||||
|
||||
AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
|
||||
if (messages.empty()) {
|
||||
on_new_message.GetWritableEvent().Clear();
|
||||
on_new_message->GetWritableEvent().Clear();
|
||||
return AppletMessage::NoMessage;
|
||||
}
|
||||
auto msg = messages.front();
|
||||
messages.pop();
|
||||
if (messages.empty()) {
|
||||
on_new_message.GetWritableEvent().Clear();
|
||||
on_new_message->GetWritableEvent().Clear();
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
@@ -637,7 +635,7 @@ void AppletMessageQueue::FocusStateChanged() {
|
||||
void AppletMessageQueue::OperationModeChanged() {
|
||||
PushMessage(AppletMessage::OperationModeChanged);
|
||||
PushMessage(AppletMessage::PerformanceModeChanged);
|
||||
on_operation_mode_changed.GetWritableEvent().Signal();
|
||||
on_operation_mode_changed->GetWritableEvent().Signal();
|
||||
}
|
||||
|
||||
ICommonStateGetter::ICommonStateGetter(Core::System& system_,
|
||||
@@ -1272,10 +1270,8 @@ void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx)
|
||||
}
|
||||
|
||||
IApplicationFunctions::IApplicationFunctions(Core::System& system_)
|
||||
: ServiceFramework{system_, "IApplicationFunctions"}, gpu_error_detected_event{system.Kernel()},
|
||||
friend_invitation_storage_channel_event{system.Kernel()},
|
||||
notification_storage_channel_event{system.Kernel()}, health_warning_disappeared_system_event{
|
||||
system.Kernel()} {
|
||||
: ServiceFramework{system_, "IApplicationFunctions"}, service_context{system,
|
||||
"IApplicationFunctions"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
|
||||
@@ -1343,21 +1339,22 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(gpu_error_detected_event));
|
||||
Kernel::KAutoObject::Create(std::addressof(friend_invitation_storage_channel_event));
|
||||
Kernel::KAutoObject::Create(std::addressof(notification_storage_channel_event));
|
||||
Kernel::KAutoObject::Create(std::addressof(health_warning_disappeared_system_event));
|
||||
|
||||
gpu_error_detected_event.Initialize("IApplicationFunctions:GpuErrorDetectedSystemEvent");
|
||||
friend_invitation_storage_channel_event.Initialize(
|
||||
"IApplicationFunctions:FriendInvitationStorageChannelEvent");
|
||||
notification_storage_channel_event.Initialize(
|
||||
"IApplicationFunctions:NotificationStorageChannelEvent");
|
||||
health_warning_disappeared_system_event.Initialize(
|
||||
"IApplicationFunctions:HealthWarningDisappearedSystemEvent");
|
||||
gpu_error_detected_event =
|
||||
service_context.CreateEvent("IApplicationFunctions:GpuErrorDetectedSystemEvent");
|
||||
friend_invitation_storage_channel_event =
|
||||
service_context.CreateEvent("IApplicationFunctions:FriendInvitationStorageChannelEvent");
|
||||
notification_storage_channel_event =
|
||||
service_context.CreateEvent("IApplicationFunctions:NotificationStorageChannelEvent");
|
||||
health_warning_disappeared_system_event =
|
||||
service_context.CreateEvent("IApplicationFunctions:HealthWarningDisappearedSystemEvent");
|
||||
}
|
||||
|
||||
IApplicationFunctions::~IApplicationFunctions() = default;
|
||||
IApplicationFunctions::~IApplicationFunctions() {
|
||||
service_context.CloseEvent(gpu_error_detected_event);
|
||||
service_context.CloseEvent(friend_invitation_storage_channel_event);
|
||||
service_context.CloseEvent(notification_storage_channel_event);
|
||||
service_context.CloseEvent(health_warning_disappeared_system_event);
|
||||
}
|
||||
|
||||
void IApplicationFunctions::EnableApplicationCrashReport(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
@@ -1751,7 +1748,7 @@ void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestCon
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(gpu_error_detected_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(gpu_error_detected_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx) {
|
||||
@@ -1759,7 +1756,7 @@ void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERe
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(friend_invitation_storage_channel_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(friend_invitation_storage_channel_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(
|
||||
@@ -1775,7 +1772,7 @@ void IApplicationFunctions::GetNotificationStorageChannelEvent(Kernel::HLEReques
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(notification_storage_channel_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(notification_storage_channel_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(Kernel::HLERequestContext& ctx) {
|
||||
@@ -1783,12 +1780,12 @@ void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(Kernel::HLERe
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(health_warning_disappeared_system_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(health_warning_disappeared_system_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
|
||||
Core::System& system) {
|
||||
auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel());
|
||||
auto message_queue = std::make_shared<AppletMessageQueue>(system);
|
||||
// Needed on game boot
|
||||
message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
|
||||
|
||||
@@ -1801,8 +1798,8 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger
|
||||
}
|
||||
|
||||
IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
|
||||
: ServiceFramework{system_, "IHomeMenuFunctions"}, pop_from_general_channel_event{
|
||||
system.Kernel()} {
|
||||
: ServiceFramework{system_, "IHomeMenuFunctions"}, service_context{system,
|
||||
"IHomeMenuFunctions"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"},
|
||||
@@ -1823,11 +1820,13 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(pop_from_general_channel_event));
|
||||
pop_from_general_channel_event.Initialize("IHomeMenuFunctions:PopFromGeneralChannelEvent");
|
||||
pop_from_general_channel_event =
|
||||
service_context.CreateEvent("IHomeMenuFunctions:PopFromGeneralChannelEvent");
|
||||
}
|
||||
|
||||
IHomeMenuFunctions::~IHomeMenuFunctions() = default;
|
||||
IHomeMenuFunctions::~IHomeMenuFunctions() {
|
||||
service_context.CloseEvent(pop_from_general_channel_event);
|
||||
}
|
||||
|
||||
void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
@@ -1841,7 +1840,7 @@ void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(Kernel::HLERequestContext
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(pop_from_general_channel_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(pop_from_general_channel_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
IGlobalStateController::IGlobalStateController(Core::System& system_)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Kernel {
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
PerformanceModeChanged = 31,
|
||||
};
|
||||
|
||||
explicit AppletMessageQueue(Kernel::KernelCore& kernel);
|
||||
explicit AppletMessageQueue(Core::System& system);
|
||||
~AppletMessageQueue();
|
||||
|
||||
Kernel::KReadableEvent& GetMessageReceiveEvent();
|
||||
@@ -66,9 +66,12 @@ public:
|
||||
void OperationModeChanged();
|
||||
|
||||
private:
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* on_new_message;
|
||||
Kernel::KEvent* on_operation_mode_changed;
|
||||
|
||||
std::queue<AppletMessage> messages;
|
||||
Kernel::KEvent on_new_message;
|
||||
Kernel::KEvent on_operation_mode_changed;
|
||||
};
|
||||
|
||||
class IWindowController final : public ServiceFramework<IWindowController> {
|
||||
@@ -156,8 +159,11 @@ private:
|
||||
};
|
||||
|
||||
NVFlinger::NVFlinger& nvflinger;
|
||||
Kernel::KEvent launchable_event;
|
||||
Kernel::KEvent accumulated_suspended_tick_changed_event;
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* launchable_event;
|
||||
Kernel::KEvent* accumulated_suspended_tick_changed_event;
|
||||
|
||||
u32 idle_time_detection_extension = 0;
|
||||
u64 num_fatal_sections_entered = 0;
|
||||
@@ -298,13 +304,15 @@ private:
|
||||
void GetNotificationStorageChannelEvent(Kernel::HLERequestContext& ctx);
|
||||
void GetHealthWarningDisappearedSystemEvent(Kernel::HLERequestContext& ctx);
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
bool launch_popped_application_specific = false;
|
||||
bool launch_popped_account_preselect = false;
|
||||
s32 previous_program_index{-1};
|
||||
Kernel::KEvent gpu_error_detected_event;
|
||||
Kernel::KEvent friend_invitation_storage_channel_event;
|
||||
Kernel::KEvent notification_storage_channel_event;
|
||||
Kernel::KEvent health_warning_disappeared_system_event;
|
||||
Kernel::KEvent* gpu_error_detected_event;
|
||||
Kernel::KEvent* friend_invitation_storage_channel_event;
|
||||
Kernel::KEvent* notification_storage_channel_event;
|
||||
Kernel::KEvent* health_warning_disappeared_system_event;
|
||||
};
|
||||
|
||||
class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
|
||||
@@ -316,7 +324,9 @@ private:
|
||||
void RequestToGetForeground(Kernel::HLERequestContext& ctx);
|
||||
void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx);
|
||||
|
||||
Kernel::KEvent pop_from_general_channel_event;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* pop_from_general_channel_event;
|
||||
};
|
||||
|
||||
class IGlobalStateController final : public ServiceFramework<IGlobalStateController> {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "core/hle/service/am/applets/applet_web_browser.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/hle/service/ns/pl_u.h"
|
||||
#include "core/loader/loader.h"
|
||||
|
||||
namespace Service::AM::Applets {
|
||||
|
||||
@@ -122,6 +123,15 @@ FileSys::VirtualFile GetOfflineRomFS(Core::System& system, u64 title_id,
|
||||
const auto nca = system.GetContentProvider().GetEntry(title_id, nca_type);
|
||||
|
||||
if (nca == nullptr) {
|
||||
if (nca_type == FileSys::ContentRecordType::HtmlDocument) {
|
||||
LOG_WARNING(Service_AM, "Falling back to AppLoader to get the RomFS.");
|
||||
FileSys::VirtualFile romfs;
|
||||
system.GetAppLoader().ReadManualRomFS(romfs);
|
||||
if (romfs != nullptr) {
|
||||
return romfs;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR(Service_AM,
|
||||
"NCA of type={} with title_id={:016X} is not found in the ContentProvider!",
|
||||
nca_type, title_id);
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
#include "core/frontend/applets/profile_select.h"
|
||||
#include "core/frontend/applets/software_keyboard.h"
|
||||
#include "core/frontend/applets/web_browser.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/k_writable_event.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/am/am.h"
|
||||
#include "core/hle/service/am/applet_ae.h"
|
||||
#include "core/hle/service/am/applet_oe.h"
|
||||
@@ -29,19 +28,19 @@
|
||||
namespace Service::AM::Applets {
|
||||
|
||||
AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_)
|
||||
: system{system_}, applet_mode{applet_mode_}, state_changed_event{system.Kernel()},
|
||||
pop_out_data_event{system.Kernel()}, pop_interactive_out_data_event{system.Kernel()} {
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(state_changed_event));
|
||||
Kernel::KAutoObject::Create(std::addressof(pop_out_data_event));
|
||||
Kernel::KAutoObject::Create(std::addressof(pop_interactive_out_data_event));
|
||||
|
||||
state_changed_event.Initialize("ILibraryAppletAccessor:StateChangedEvent");
|
||||
pop_out_data_event.Initialize("ILibraryAppletAccessor:PopDataOutEvent");
|
||||
pop_interactive_out_data_event.Initialize("ILibraryAppletAccessor:PopInteractiveDataOutEvent");
|
||||
: system{system_}, applet_mode{applet_mode_}, service_context{system,
|
||||
"ILibraryAppletAccessor"} {
|
||||
state_changed_event = service_context.CreateEvent("ILibraryAppletAccessor:StateChangedEvent");
|
||||
pop_out_data_event = service_context.CreateEvent("ILibraryAppletAccessor:PopDataOutEvent");
|
||||
pop_interactive_out_data_event =
|
||||
service_context.CreateEvent("ILibraryAppletAccessor:PopInteractiveDataOutEvent");
|
||||
}
|
||||
|
||||
AppletDataBroker::~AppletDataBroker() = default;
|
||||
AppletDataBroker::~AppletDataBroker() {
|
||||
service_context.CloseEvent(state_changed_event);
|
||||
service_context.CloseEvent(pop_out_data_event);
|
||||
service_context.CloseEvent(pop_interactive_out_data_event);
|
||||
}
|
||||
|
||||
AppletDataBroker::RawChannelData AppletDataBroker::PeekDataToAppletForDebug() const {
|
||||
std::vector<std::vector<u8>> out_normal;
|
||||
@@ -65,7 +64,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
|
||||
|
||||
auto out = std::move(out_channel.front());
|
||||
out_channel.pop_front();
|
||||
pop_out_data_event.GetWritableEvent().Clear();
|
||||
pop_out_data_event->GetWritableEvent().Clear();
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -84,7 +83,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() {
|
||||
|
||||
auto out = std::move(out_interactive_channel.front());
|
||||
out_interactive_channel.pop_front();
|
||||
pop_interactive_out_data_event.GetWritableEvent().Clear();
|
||||
pop_interactive_out_data_event->GetWritableEvent().Clear();
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -103,7 +102,7 @@ void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storag
|
||||
|
||||
void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) {
|
||||
out_channel.emplace_back(std::move(storage));
|
||||
pop_out_data_event.GetWritableEvent().Signal();
|
||||
pop_out_data_event->GetWritableEvent().Signal();
|
||||
}
|
||||
|
||||
void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) {
|
||||
@@ -112,11 +111,11 @@ void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& s
|
||||
|
||||
void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) {
|
||||
out_interactive_channel.emplace_back(std::move(storage));
|
||||
pop_interactive_out_data_event.GetWritableEvent().Signal();
|
||||
pop_interactive_out_data_event->GetWritableEvent().Signal();
|
||||
}
|
||||
|
||||
void AppletDataBroker::SignalStateChanged() {
|
||||
state_changed_event.GetWritableEvent().Signal();
|
||||
state_changed_event->GetWritableEvent().Signal();
|
||||
|
||||
switch (applet_mode) {
|
||||
case LibraryAppletMode::AllForeground:
|
||||
@@ -141,15 +140,15 @@ void AppletDataBroker::SignalStateChanged() {
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent& AppletDataBroker::GetNormalDataEvent() {
|
||||
return pop_out_data_event.GetReadableEvent();
|
||||
return pop_out_data_event->GetReadableEvent();
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent& AppletDataBroker::GetInteractiveDataEvent() {
|
||||
return pop_interactive_out_data_event.GetReadableEvent();
|
||||
return pop_interactive_out_data_event->GetReadableEvent();
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent& AppletDataBroker::GetStateChangedEvent() {
|
||||
return state_changed_event.GetReadableEvent();
|
||||
return state_changed_event->GetReadableEvent();
|
||||
}
|
||||
|
||||
Applet::Applet(Core::System& system_, LibraryAppletMode applet_mode_)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <queue>
|
||||
|
||||
#include "common/swap.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
|
||||
union ResultCode;
|
||||
|
||||
@@ -105,6 +105,8 @@ private:
|
||||
Core::System& system;
|
||||
LibraryAppletMode applet_mode;
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
// Queues are named from applet's perspective
|
||||
|
||||
// PopNormalDataToApplet and PushNormalDataFromGame
|
||||
@@ -119,13 +121,13 @@ private:
|
||||
// PopInteractiveDataToGame and PushInteractiveDataFromApplet
|
||||
std::deque<std::shared_ptr<IStorage>> out_interactive_channel;
|
||||
|
||||
Kernel::KEvent state_changed_event;
|
||||
Kernel::KEvent* state_changed_event;
|
||||
|
||||
// Signaled on PushNormalDataFromApplet
|
||||
Kernel::KEvent pop_out_data_event;
|
||||
Kernel::KEvent* pop_out_data_event;
|
||||
|
||||
// Signaled on PushInteractiveDataFromApplet
|
||||
Kernel::KEvent pop_interactive_out_data_event;
|
||||
Kernel::KEvent* pop_interactive_out_data_event;
|
||||
};
|
||||
|
||||
class Applet {
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
#include "core/file_sys/registered_cache.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/aoc/aoc_u.h"
|
||||
#include "core/loader/loader.h"
|
||||
@@ -49,7 +49,8 @@ static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) {
|
||||
class IPurchaseEventManager final : public ServiceFramework<IPurchaseEventManager> {
|
||||
public:
|
||||
explicit IPurchaseEventManager(Core::System& system_)
|
||||
: ServiceFramework{system_, "IPurchaseEventManager"}, purchased_event{system.Kernel()} {
|
||||
: ServiceFramework{system_, "IPurchaseEventManager"}, service_context{
|
||||
system, "IPurchaseEventManager"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IPurchaseEventManager::SetDefaultDeliveryTarget, "SetDefaultDeliveryTarget"},
|
||||
@@ -62,8 +63,11 @@ public:
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(purchased_event));
|
||||
purchased_event.Initialize("IPurchaseEventManager:PurchasedEvent");
|
||||
purchased_event = service_context.CreateEvent("IPurchaseEventManager:PurchasedEvent");
|
||||
}
|
||||
|
||||
~IPurchaseEventManager() override {
|
||||
service_context.CloseEvent(purchased_event);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -96,15 +100,17 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(purchased_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(purchased_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
Kernel::KEvent purchased_event;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* purchased_event;
|
||||
};
|
||||
|
||||
AOC_U::AOC_U(Core::System& system_)
|
||||
: ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)},
|
||||
aoc_change_event{system.Kernel()} {
|
||||
service_context{system_, "aoc:u"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "CountAddOnContentByApplicationId"},
|
||||
@@ -126,11 +132,12 @@ AOC_U::AOC_U(Core::System& system_)
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(aoc_change_event));
|
||||
aoc_change_event.Initialize("GetAddOnContentListChanged:Event");
|
||||
aoc_change_event = service_context.CreateEvent("GetAddOnContentListChanged:Event");
|
||||
}
|
||||
|
||||
AOC_U::~AOC_U() = default;
|
||||
AOC_U::~AOC_U() {
|
||||
service_context.CloseEvent(aoc_change_event);
|
||||
}
|
||||
|
||||
void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) {
|
||||
struct Parameters {
|
||||
@@ -254,7 +261,7 @@ void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(aoc_change_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(aoc_change_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void AOC_U::GetAddOnContentListChangedEventWithProcessId(Kernel::HLERequestContext& ctx) {
|
||||
@@ -262,7 +269,7 @@ void AOC_U::GetAddOnContentListChangedEventWithProcessId(Kernel::HLERequestConte
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(aoc_change_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(aoc_change_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void AOC_U::CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
@@ -33,7 +33,9 @@ private:
|
||||
void CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx);
|
||||
|
||||
std::vector<u64> add_on_content;
|
||||
Kernel::KEvent aoc_change_event;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* aoc_change_event;
|
||||
};
|
||||
|
||||
/// Registers all AOC services with the specified service manager.
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/audio/audin_u.h"
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
IAudioIn::IAudioIn(Core::System& system_)
|
||||
: ServiceFramework{system_, "IAudioIn"}, buffer_event{system_.Kernel()} {
|
||||
: ServiceFramework{system_, "IAudioIn"}, service_context{system_, "IAudioIn"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetAudioInState"},
|
||||
@@ -35,11 +34,12 @@ IAudioIn::IAudioIn(Core::System& system_)
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(buffer_event));
|
||||
buffer_event.Initialize("IAudioIn:BufferEvent");
|
||||
buffer_event = service_context.CreateEvent("IAudioIn:BufferEvent");
|
||||
}
|
||||
|
||||
IAudioIn::~IAudioIn() = default;
|
||||
IAudioIn::~IAudioIn() {
|
||||
service_context.CloseEvent(buffer_event);
|
||||
}
|
||||
|
||||
void IAudioIn::Start(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
@@ -53,7 +53,7 @@ void IAudioIn::RegisterBufferEvent(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(buffer_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(buffer_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void IAudioIn::AppendAudioInBufferAuto(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
@@ -27,7 +27,9 @@ private:
|
||||
void RegisterBufferEvent(Kernel::HLERequestContext& ctx);
|
||||
void AppendAudioInBufferAuto(Kernel::HLERequestContext& ctx);
|
||||
|
||||
Kernel::KEvent buffer_event;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* buffer_event;
|
||||
};
|
||||
|
||||
class AudInU final : public ServiceFramework<AudInU> {
|
||||
|
||||
@@ -13,13 +13,11 @@
|
||||
#include "common/swap.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/k_writable_event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/audio/audout_u.h"
|
||||
#include "core/hle/service/audio/errors.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace Service::Audio {
|
||||
@@ -41,11 +39,12 @@ enum class AudioState : u32 {
|
||||
|
||||
class IAudioOut final : public ServiceFramework<IAudioOut> {
|
||||
public:
|
||||
IAudioOut(Core::System& system_, AudoutParams audio_params_, AudioCore::AudioOut& audio_core_,
|
||||
std::string&& device_name_, std::string&& unique_name)
|
||||
: ServiceFramework{system_, "IAudioOut"}, audio_core{audio_core_}, device_name{std::move(
|
||||
device_name_)},
|
||||
audio_params{audio_params_}, buffer_event{system.Kernel()}, main_memory{system.Memory()} {
|
||||
explicit IAudioOut(Core::System& system_, AudoutParams audio_params_,
|
||||
AudioCore::AudioOut& audio_core_, std::string&& device_name_,
|
||||
std::string&& unique_name)
|
||||
: ServiceFramework{system_, "IAudioOut"}, audio_core{audio_core_},
|
||||
device_name{std::move(device_name_)}, audio_params{audio_params_},
|
||||
main_memory{system.Memory()}, service_context{system_, "IAudioOut"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
|
||||
@@ -67,16 +66,19 @@ public:
|
||||
RegisterHandlers(functions);
|
||||
|
||||
// This is the event handle used to check if the audio buffer was released
|
||||
Kernel::KAutoObject::Create(std::addressof(buffer_event));
|
||||
buffer_event.Initialize("IAudioOutBufferReleased");
|
||||
buffer_event = service_context.CreateEvent("IAudioOutBufferReleased");
|
||||
|
||||
stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate,
|
||||
audio_params.channel_count, std::move(unique_name), [this] {
|
||||
const auto guard = LockService();
|
||||
buffer_event.GetWritableEvent().Signal();
|
||||
buffer_event->GetWritableEvent().Signal();
|
||||
});
|
||||
}
|
||||
|
||||
~IAudioOut() override {
|
||||
service_context.CloseEvent(buffer_event);
|
||||
}
|
||||
|
||||
private:
|
||||
struct AudioBuffer {
|
||||
u64_le next;
|
||||
@@ -126,7 +128,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(buffer_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(buffer_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) {
|
||||
@@ -227,9 +229,12 @@ private:
|
||||
|
||||
[[maybe_unused]] AudoutParams audio_params{};
|
||||
|
||||
/// This is the event handle used to check if the audio buffer was released
|
||||
Kernel::KEvent buffer_event;
|
||||
Core::Memory::Memory& main_memory;
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
/// This is the event handle used to check if the audio buffer was released
|
||||
Kernel::KEvent* buffer_event;
|
||||
};
|
||||
|
||||
AudOutU::AudOutU(Core::System& system_) : ServiceFramework{system_, "audout:u"} {
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/k_writable_event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/audio/audren_u.h"
|
||||
#include "core/hle/service/audio/errors.h"
|
||||
@@ -30,7 +27,7 @@ public:
|
||||
explicit IAudioRenderer(Core::System& system_,
|
||||
const AudioCommon::AudioRendererParameter& audren_params,
|
||||
const std::size_t instance_number)
|
||||
: ServiceFramework{system_, "IAudioRenderer"}, system_event{system.Kernel()} {
|
||||
: ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IAudioRenderer::GetSampleRate, "GetSampleRate"},
|
||||
@@ -49,17 +46,20 @@ public:
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(system_event));
|
||||
system_event.Initialize("IAudioRenderer:SystemEvent");
|
||||
system_event = service_context.CreateEvent("IAudioRenderer:SystemEvent");
|
||||
renderer = std::make_unique<AudioCore::AudioRenderer>(
|
||||
system.CoreTiming(), system.Memory(), audren_params,
|
||||
[this]() {
|
||||
const auto guard = LockService();
|
||||
system_event.GetWritableEvent().Signal();
|
||||
system_event->GetWritableEvent().Signal();
|
||||
},
|
||||
instance_number);
|
||||
}
|
||||
|
||||
~IAudioRenderer() override {
|
||||
service_context.CloseEvent(system_event);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetSampleRate(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_Audio, "called");
|
||||
@@ -130,7 +130,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(system_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(system_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void SetRenderingTimeLimit(Kernel::HLERequestContext& ctx) {
|
||||
@@ -164,14 +164,16 @@ private:
|
||||
rb.Push(ERR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
Kernel::KEvent system_event;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* system_event;
|
||||
std::unique_ptr<AudioCore::AudioRenderer> renderer;
|
||||
u32 rendering_time_limit_percent = 100;
|
||||
};
|
||||
|
||||
class IAudioDevice final : public ServiceFramework<IAudioDevice> {
|
||||
public:
|
||||
explicit IAudioDevice(Core::System& system_, Kernel::KEvent& buffer_event_, u32_le revision_)
|
||||
explicit IAudioDevice(Core::System& system_, Kernel::KEvent* buffer_event_, u32_le revision_)
|
||||
: ServiceFramework{system_, "IAudioDevice"}, buffer_event{buffer_event_}, revision{
|
||||
revision_} {
|
||||
static const FunctionInfo functions[] = {
|
||||
@@ -279,11 +281,11 @@ private:
|
||||
void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
|
||||
buffer_event.GetWritableEvent().Signal();
|
||||
buffer_event->GetWritableEvent().Signal();
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(buffer_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(buffer_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void GetActiveChannelCount(Kernel::HLERequestContext& ctx) {
|
||||
@@ -300,7 +302,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(buffer_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(buffer_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void QueryAudioDeviceOutputEvent(Kernel::HLERequestContext& ctx) {
|
||||
@@ -308,16 +310,15 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(buffer_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(buffer_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
Kernel::KEvent& buffer_event;
|
||||
Kernel::KEvent* buffer_event;
|
||||
u32_le revision = 0;
|
||||
};
|
||||
|
||||
AudRenU::AudRenU(Core::System& system_)
|
||||
: ServiceFramework{system_, "audren:u"}, buffer_event{system.Kernel()} {
|
||||
|
||||
: ServiceFramework{system_, "audren:u"}, service_context{system_, "audren:u"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"},
|
||||
@@ -330,11 +331,12 @@ AudRenU::AudRenU(Core::System& system_)
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(buffer_event));
|
||||
buffer_event.Initialize("IAudioOutBufferReleasedEvent");
|
||||
buffer_event = service_context.CreateEvent("IAudioOutBufferReleasedEvent");
|
||||
}
|
||||
|
||||
AudRenU::~AudRenU() = default;
|
||||
AudRenU::~AudRenU() {
|
||||
service_context.CloseEvent(buffer_event);
|
||||
}
|
||||
|
||||
void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_Audio, "called");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
@@ -31,8 +31,10 @@ private:
|
||||
|
||||
void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx);
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
std::size_t audren_instance_count = 0;
|
||||
Kernel::KEvent buffer_event;
|
||||
Kernel::KEvent* buffer_event;
|
||||
};
|
||||
|
||||
// Describes a particular audio feature that may be supported in a particular revision.
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/audio/hwopus.h"
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
@@ -5,22 +5,24 @@
|
||||
#include "common/hex_util.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/k_writable_event.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/lock.h"
|
||||
#include "core/hle/service/bcat/backend/backend.h"
|
||||
|
||||
namespace Service::BCAT {
|
||||
|
||||
ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel,
|
||||
std::string_view event_name)
|
||||
: update_event{kernel} {
|
||||
Kernel::KAutoObject::Create(std::addressof(update_event));
|
||||
update_event.Initialize("ProgressServiceBackend:UpdateEvent:" + std::string(event_name));
|
||||
ProgressServiceBackend::ProgressServiceBackend(Core::System& system, std::string_view event_name)
|
||||
: service_context{system, "ProgressServiceBackend"} {
|
||||
update_event = service_context.CreateEvent("ProgressServiceBackend:UpdateEvent:" +
|
||||
std::string(event_name));
|
||||
}
|
||||
|
||||
ProgressServiceBackend::~ProgressServiceBackend() {
|
||||
service_context.CloseEvent(update_event);
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent& ProgressServiceBackend::GetEvent() {
|
||||
return update_event.GetReadableEvent();
|
||||
return update_event->GetReadableEvent();
|
||||
}
|
||||
|
||||
DeliveryCacheProgressImpl& ProgressServiceBackend::GetImpl() {
|
||||
@@ -88,9 +90,9 @@ void ProgressServiceBackend::FinishDownload(ResultCode result) {
|
||||
void ProgressServiceBackend::SignalUpdate() {
|
||||
if (need_hle_lock) {
|
||||
std::lock_guard lock(HLE::g_hle_lock);
|
||||
update_event.GetWritableEvent().Signal();
|
||||
update_event->GetWritableEvent().Signal();
|
||||
} else {
|
||||
update_event.GetWritableEvent().Signal();
|
||||
update_event->GetWritableEvent().Signal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/file_sys/vfs_types.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
@@ -70,6 +70,8 @@ class ProgressServiceBackend {
|
||||
friend class IBcatService;
|
||||
|
||||
public:
|
||||
~ProgressServiceBackend();
|
||||
|
||||
// Clients should call this with true if any of the functions are going to be called from a
|
||||
// non-HLE thread and this class need to lock the hle mutex. (default is false)
|
||||
void SetNeedHLELock(bool need);
|
||||
@@ -97,15 +99,17 @@ public:
|
||||
void FinishDownload(ResultCode result);
|
||||
|
||||
private:
|
||||
explicit ProgressServiceBackend(Kernel::KernelCore& kernel, std::string_view event_name);
|
||||
explicit ProgressServiceBackend(Core::System& system, std::string_view event_name);
|
||||
|
||||
Kernel::KReadableEvent& GetEvent();
|
||||
DeliveryCacheProgressImpl& GetImpl();
|
||||
|
||||
void SignalUpdate();
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
DeliveryCacheProgressImpl impl{};
|
||||
Kernel::KEvent update_event;
|
||||
Kernel::KEvent* update_event;
|
||||
bool need_hle_lock = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -127,8 +127,8 @@ public:
|
||||
explicit IBcatService(Core::System& system_, Backend& backend_)
|
||||
: ServiceFramework{system_, "IBcatService"}, backend{backend_},
|
||||
progress{{
|
||||
ProgressServiceBackend{system_.Kernel(), "Normal"},
|
||||
ProgressServiceBackend{system_.Kernel(), "Directory"},
|
||||
ProgressServiceBackend{system_, "Normal"},
|
||||
ProgressServiceBackend{system_, "Directory"},
|
||||
}} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
|
||||
@@ -5,11 +5,10 @@
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/btdrv/btdrv.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
|
||||
@@ -18,7 +17,7 @@ namespace Service::BtDrv {
|
||||
class Bt final : public ServiceFramework<Bt> {
|
||||
public:
|
||||
explicit Bt(Core::System& system_)
|
||||
: ServiceFramework{system_, "bt"}, register_event{system.Kernel()} {
|
||||
: ServiceFramework{system_, "bt"}, service_context{system_, "bt"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "LeClientReadCharacteristic"},
|
||||
@@ -35,8 +34,11 @@ public:
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(register_event));
|
||||
register_event.Initialize("BT:RegisterEvent");
|
||||
register_event = service_context.CreateEvent("BT:RegisterEvent");
|
||||
}
|
||||
|
||||
~Bt() override {
|
||||
service_context.CloseEvent(register_event);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -45,10 +47,12 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(register_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(register_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
Kernel::KEvent register_event;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* register_event;
|
||||
};
|
||||
|
||||
class BtDrv final : public ServiceFramework<BtDrv> {
|
||||
|
||||
@@ -7,11 +7,10 @@
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/btm/btm.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::BTM {
|
||||
@@ -19,9 +18,7 @@ namespace Service::BTM {
|
||||
class IBtmUserCore final : public ServiceFramework<IBtmUserCore> {
|
||||
public:
|
||||
explicit IBtmUserCore(Core::System& system_)
|
||||
: ServiceFramework{system_, "IBtmUserCore"}, scan_event{system.Kernel()},
|
||||
connection_event{system.Kernel()}, service_discovery{system.Kernel()},
|
||||
config_event{system.Kernel()} {
|
||||
: ServiceFramework{system_, "IBtmUserCore"}, service_context{system_, "IBtmUserCore"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"},
|
||||
@@ -60,15 +57,17 @@ public:
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(scan_event));
|
||||
Kernel::KAutoObject::Create(std::addressof(connection_event));
|
||||
Kernel::KAutoObject::Create(std::addressof(service_discovery));
|
||||
Kernel::KAutoObject::Create(std::addressof(config_event));
|
||||
scan_event = service_context.CreateEvent("IBtmUserCore:ScanEvent");
|
||||
connection_event = service_context.CreateEvent("IBtmUserCore:ConnectionEvent");
|
||||
service_discovery_event = service_context.CreateEvent("IBtmUserCore:DiscoveryEvent");
|
||||
config_event = service_context.CreateEvent("IBtmUserCore:ConfigEvent");
|
||||
}
|
||||
|
||||
scan_event.Initialize("IBtmUserCore:ScanEvent");
|
||||
connection_event.Initialize("IBtmUserCore:ConnectionEvent");
|
||||
service_discovery.Initialize("IBtmUserCore:Discovery");
|
||||
config_event.Initialize("IBtmUserCore:ConfigEvent");
|
||||
~IBtmUserCore() override {
|
||||
service_context.CloseEvent(scan_event);
|
||||
service_context.CloseEvent(connection_event);
|
||||
service_context.CloseEvent(service_discovery_event);
|
||||
service_context.CloseEvent(config_event);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -77,7 +76,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(scan_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(scan_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void AcquireBleConnectionEvent(Kernel::HLERequestContext& ctx) {
|
||||
@@ -85,7 +84,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(connection_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(connection_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void AcquireBleServiceDiscoveryEvent(Kernel::HLERequestContext& ctx) {
|
||||
@@ -93,7 +92,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(service_discovery.GetReadableEvent());
|
||||
rb.PushCopyObjects(service_discovery_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void AcquireBleMtuConfigEvent(Kernel::HLERequestContext& ctx) {
|
||||
@@ -101,13 +100,15 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(config_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(config_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
Kernel::KEvent scan_event;
|
||||
Kernel::KEvent connection_event;
|
||||
Kernel::KEvent service_discovery;
|
||||
Kernel::KEvent config_event;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* scan_event;
|
||||
Kernel::KEvent* connection_event;
|
||||
Kernel::KEvent* service_discovery_event;
|
||||
Kernel::KEvent* config_event;
|
||||
};
|
||||
|
||||
class BTM_USR final : public ServiceFramework<BTM_USR> {
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <memory>
|
||||
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/fgm/fgm.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/service/filesystem/fsp_ldr.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::FileSystem {
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/service/filesystem/fsp_pr.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::FileSystem {
|
||||
|
||||
|
||||
@@ -8,11 +8,10 @@
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/k_writable_event.h"
|
||||
#include "core/hle/service/friend/errors.h"
|
||||
#include "core/hle/service/friend/friend.h"
|
||||
#include "core/hle/service/friend/friend_interface.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
|
||||
namespace Service::Friend {
|
||||
|
||||
@@ -184,9 +183,9 @@ private:
|
||||
|
||||
class INotificationService final : public ServiceFramework<INotificationService> {
|
||||
public:
|
||||
explicit INotificationService(Common::UUID uuid_, Core::System& system_)
|
||||
: ServiceFramework{system_, "INotificationService"}, uuid{uuid_}, notification_event{
|
||||
system.Kernel()} {
|
||||
explicit INotificationService(Core::System& system_, Common::UUID uuid_)
|
||||
: ServiceFramework{system_, "INotificationService"}, uuid{uuid_},
|
||||
service_context{system_, "INotificationService"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &INotificationService::GetEvent, "GetEvent"},
|
||||
@@ -197,8 +196,11 @@ public:
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(notification_event));
|
||||
notification_event.Initialize("INotificationService:NotifyEvent");
|
||||
notification_event = service_context.CreateEvent("INotificationService:NotifyEvent");
|
||||
}
|
||||
|
||||
~INotificationService() override {
|
||||
service_context.CloseEvent(notification_event);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -207,7 +209,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(notification_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(notification_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void Clear(Kernel::HLERequestContext& ctx) {
|
||||
@@ -272,8 +274,10 @@ private:
|
||||
bool has_received_friend_request;
|
||||
};
|
||||
|
||||
Common::UUID uuid{Common::INVALID_UUID};
|
||||
Kernel::KEvent notification_event;
|
||||
Common::UUID uuid;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* notification_event;
|
||||
std::queue<SizedNotificationInfo> notifications;
|
||||
States states{};
|
||||
};
|
||||
@@ -293,7 +297,7 @@ void Module::Interface::CreateNotificationService(Kernel::HLERequestContext& ctx
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushIpcInterface<INotificationService>(uuid, system);
|
||||
rb.PushIpcInterface<INotificationService>(system, uuid);
|
||||
}
|
||||
|
||||
Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_,
|
||||
|
||||
@@ -8,13 +8,11 @@
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/control_metadata.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/glue/arp.h"
|
||||
#include "core/hle/service/glue/errors.h"
|
||||
#include "core/hle/service/glue/glue_manager.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::Glue {
|
||||
|
||||
|
||||
@@ -8,12 +8,9 @@
|
||||
#include "common/settings.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/core_timing_util.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/hardware_properties.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_client_port.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/k_shared_memory.h"
|
||||
#include "core/hle/kernel/k_transfer_memory.h"
|
||||
@@ -23,7 +20,6 @@
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
#include "core/hle/service/hid/irs.h"
|
||||
#include "core/hle/service/hid/xcd.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
#include "core/hle/service/hid/controllers/console_sixaxis.h"
|
||||
@@ -106,7 +102,7 @@ void IAppletResource::DeactivateController(HidController controller) {
|
||||
controllers[static_cast<size_t>(controller)]->DeactivateController();
|
||||
}
|
||||
|
||||
IAppletResource ::~IAppletResource() {
|
||||
IAppletResource::~IAppletResource() {
|
||||
system.CoreTiming().UnscheduleEvent(pad_update_event, 0);
|
||||
system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/lbl/lbl.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/mii/mii.h"
|
||||
#include "core/hle/service/mii/mii_manager.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/nfc/nfc.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
|
||||
@@ -8,9 +8,8 @@
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_thread.h"
|
||||
#include "core/hle/kernel/k_writable_event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/lock.h"
|
||||
#include "core/hle/service/nfp/nfp.h"
|
||||
@@ -23,18 +22,21 @@ constexpr ResultCode ERR_NO_APPLICATION_AREA(ErrorModule::NFP, 152);
|
||||
|
||||
Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_,
|
||||
const char* name)
|
||||
: ServiceFramework{system_, name}, nfc_tag_load{system.Kernel()}, module{std::move(module_)} {
|
||||
Kernel::KAutoObject::Create(std::addressof(nfc_tag_load));
|
||||
nfc_tag_load.Initialize("IUser:NFCTagDetected");
|
||||
: ServiceFramework{system_, name}, module{std::move(module_)}, service_context{system_,
|
||||
"NFP::IUser"} {
|
||||
nfc_tag_load = service_context.CreateEvent("NFP::IUser:NFCTagDetected");
|
||||
}
|
||||
|
||||
Module::Interface::~Interface() = default;
|
||||
Module::Interface::~Interface() {
|
||||
service_context.CloseEvent(nfc_tag_load);
|
||||
}
|
||||
|
||||
class IUser final : public ServiceFramework<IUser> {
|
||||
public:
|
||||
explicit IUser(Module::Interface& nfp_interface_, Core::System& system_)
|
||||
explicit IUser(Module::Interface& nfp_interface_, Core::System& system_,
|
||||
KernelHelpers::ServiceContext& service_context_)
|
||||
: ServiceFramework{system_, "NFP::IUser"}, nfp_interface{nfp_interface_},
|
||||
deactivate_event{system.Kernel()}, availability_change_event{system.Kernel()} {
|
||||
service_context{service_context_} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IUser::Initialize, "Initialize"},
|
||||
{1, &IUser::Finalize, "Finalize"},
|
||||
@@ -64,11 +66,14 @@ public:
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(deactivate_event));
|
||||
Kernel::KAutoObject::Create(std::addressof(availability_change_event));
|
||||
deactivate_event = service_context.CreateEvent("NFP::IUser:DeactivateEvent");
|
||||
availability_change_event =
|
||||
service_context.CreateEvent("NFP::IUser:AvailabilityChangeEvent");
|
||||
}
|
||||
|
||||
deactivate_event.Initialize("IUser:DeactivateEvent");
|
||||
availability_change_event.Initialize("IUser:AvailabilityChangeEvent");
|
||||
~IUser() override {
|
||||
service_context.CloseEvent(deactivate_event);
|
||||
service_context.CloseEvent(availability_change_event);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -166,7 +171,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(deactivate_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(deactivate_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void StopDetection(Kernel::HLERequestContext& ctx) {
|
||||
@@ -175,7 +180,7 @@ private:
|
||||
switch (device_state) {
|
||||
case DeviceState::TagFound:
|
||||
case DeviceState::TagNearby:
|
||||
deactivate_event.GetWritableEvent().Signal();
|
||||
deactivate_event->GetWritableEvent().Signal();
|
||||
device_state = DeviceState::Initialized;
|
||||
break;
|
||||
case DeviceState::SearchingForTag:
|
||||
@@ -264,7 +269,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(availability_change_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(availability_change_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void GetRegisterInfo(Kernel::HLERequestContext& ctx) {
|
||||
@@ -313,14 +318,16 @@ private:
|
||||
rb.PushRaw<u32>(0); // This is from the GetCommonInfo stub
|
||||
}
|
||||
|
||||
Module::Interface& nfp_interface;
|
||||
KernelHelpers::ServiceContext& service_context;
|
||||
|
||||
bool has_attached_handle{};
|
||||
const u64 device_handle{0}; // Npad device 1
|
||||
const u32 npad_id{0}; // Player 1 controller
|
||||
State state{State::NonInitialized};
|
||||
DeviceState device_state{DeviceState::Initialized};
|
||||
Module::Interface& nfp_interface;
|
||||
Kernel::KEvent deactivate_event;
|
||||
Kernel::KEvent availability_change_event;
|
||||
Kernel::KEvent* deactivate_event;
|
||||
Kernel::KEvent* availability_change_event;
|
||||
};
|
||||
|
||||
void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) {
|
||||
@@ -328,7 +335,7 @@ void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushIpcInterface<IUser>(*this, system);
|
||||
rb.PushIpcInterface<IUser>(*this, system, service_context);
|
||||
}
|
||||
|
||||
bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) {
|
||||
@@ -338,12 +345,12 @@ bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) {
|
||||
}
|
||||
|
||||
std::memcpy(&amiibo, buffer.data(), sizeof(amiibo));
|
||||
nfc_tag_load.GetWritableEvent().Signal();
|
||||
nfc_tag_load->GetWritableEvent().Signal();
|
||||
return true;
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent& Module::Interface::GetNFCEvent() {
|
||||
return nfc_tag_load.GetReadableEvent();
|
||||
return nfc_tag_load->GetReadableEvent();
|
||||
}
|
||||
|
||||
const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Kernel {
|
||||
@@ -42,12 +42,13 @@ public:
|
||||
Kernel::KReadableEvent& GetNFCEvent();
|
||||
const AmiiboFile& GetAmiiboBuffer() const;
|
||||
|
||||
private:
|
||||
Kernel::KEvent nfc_tag_load;
|
||||
AmiiboFile amiibo{};
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Module> module;
|
||||
|
||||
private:
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
Kernel::KEvent* nfc_tag_load;
|
||||
AmiiboFile amiibo{};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -6,10 +6,21 @@
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/nifm/nifm.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Avoids name conflict with Windows' CreateEvent macro.
|
||||
[[nodiscard]] Kernel::KEvent* CreateKEvent(Service::KernelHelpers::ServiceContext& service_context,
|
||||
std::string&& name) {
|
||||
return service_context.CreateEvent(std::move(name));
|
||||
}
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
#include "core/network/network.h"
|
||||
#include "core/network/network_interface.h"
|
||||
|
||||
@@ -129,7 +140,7 @@ public:
|
||||
class IRequest final : public ServiceFramework<IRequest> {
|
||||
public:
|
||||
explicit IRequest(Core::System& system_)
|
||||
: ServiceFramework{system_, "IRequest"}, event1{system.Kernel()}, event2{system.Kernel()} {
|
||||
: ServiceFramework{system_, "IRequest"}, service_context{system_, "IRequest"} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IRequest::GetRequestState, "GetRequestState"},
|
||||
{1, &IRequest::GetResult, "GetResult"},
|
||||
@@ -159,11 +170,13 @@ public:
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(event1));
|
||||
Kernel::KAutoObject::Create(std::addressof(event2));
|
||||
event1 = CreateKEvent(service_context, "IRequest:Event1");
|
||||
event2 = CreateKEvent(service_context, "IRequest:Event2");
|
||||
}
|
||||
|
||||
event1.Initialize("IRequest:Event1");
|
||||
event2.Initialize("IRequest:Event2");
|
||||
~IRequest() override {
|
||||
service_context.CloseEvent(event1);
|
||||
service_context.CloseEvent(event2);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -199,7 +212,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(event1.GetReadableEvent(), event2.GetReadableEvent());
|
||||
rb.PushCopyObjects(event1->GetReadableEvent(), event2->GetReadableEvent());
|
||||
}
|
||||
|
||||
void Cancel(Kernel::HLERequestContext& ctx) {
|
||||
@@ -230,7 +243,10 @@ private:
|
||||
rb.Push<u32>(0);
|
||||
}
|
||||
|
||||
Kernel::KEvent event1, event2;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* event1;
|
||||
Kernel::KEvent* event2;
|
||||
};
|
||||
|
||||
class INetworkProfile final : public ServiceFramework<INetworkProfile> {
|
||||
|
||||
@@ -7,9 +7,8 @@
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/k_writable_event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/nim/nim.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
@@ -301,7 +300,7 @@ class IEnsureNetworkClockAvailabilityService final
|
||||
public:
|
||||
explicit IEnsureNetworkClockAvailabilityService(Core::System& system_)
|
||||
: ServiceFramework{system_, "IEnsureNetworkClockAvailabilityService"},
|
||||
finished_event{system.Kernel()} {
|
||||
service_context{system_, "IEnsureNetworkClockAvailabilityService"} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IEnsureNetworkClockAvailabilityService::StartTask, "StartTask"},
|
||||
{1, &IEnsureNetworkClockAvailabilityService::GetFinishNotificationEvent,
|
||||
@@ -313,17 +312,19 @@ public:
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(finished_event));
|
||||
finished_event.Initialize("IEnsureNetworkClockAvailabilityService:FinishEvent");
|
||||
finished_event =
|
||||
service_context.CreateEvent("IEnsureNetworkClockAvailabilityService:FinishEvent");
|
||||
}
|
||||
|
||||
~IEnsureNetworkClockAvailabilityService() override {
|
||||
service_context.CloseEvent(finished_event);
|
||||
}
|
||||
|
||||
private:
|
||||
Kernel::KEvent finished_event;
|
||||
|
||||
void StartTask(Kernel::HLERequestContext& ctx) {
|
||||
// No need to connect to the internet, just finish the task straight away.
|
||||
LOG_DEBUG(Service_NIM, "called");
|
||||
finished_event.GetWritableEvent().Signal();
|
||||
finished_event->GetWritableEvent().Signal();
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
@@ -333,7 +334,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(finished_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(finished_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void GetResult(Kernel::HLERequestContext& ctx) {
|
||||
@@ -345,7 +346,7 @@ private:
|
||||
|
||||
void Cancel(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_NIM, "called");
|
||||
finished_event.GetWritableEvent().Clear();
|
||||
finished_event->GetWritableEvent().Clear();
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
@@ -368,6 +369,10 @@ private:
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushRaw<s64>(server_time);
|
||||
}
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* finished_event;
|
||||
};
|
||||
|
||||
class NTC final : public ServiceFramework<NTC> {
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
#include "core/file_sys/vfs.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/ns/errors.h"
|
||||
#include "core/hle/service/ns/language.h"
|
||||
#include "core/hle/service/ns/ns.h"
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Service::Nvidia::Devices {
|
||||
|
||||
nvdisp_disp0::nvdisp_disp0(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_)
|
||||
: nvdevice{system_}, nvmap_dev{std::move(nvmap_dev_)} {}
|
||||
nvdisp_disp0 ::~nvdisp_disp0() = default;
|
||||
nvdisp_disp0::~nvdisp_disp0() = default;
|
||||
|
||||
NvResult nvdisp_disp0::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) {
|
||||
@@ -48,8 +48,9 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3
|
||||
addr, offset, width, height, stride, format);
|
||||
|
||||
const auto pixel_format = static_cast<Tegra::FramebufferConfig::PixelFormat>(format);
|
||||
const Tegra::FramebufferConfig framebuffer{addr, offset, width, height,
|
||||
stride, pixel_format, transform, crop_rect};
|
||||
const auto transform_flags = static_cast<Tegra::FramebufferConfig::TransformFlags>(transform);
|
||||
const Tegra::FramebufferConfig framebuffer{addr, offset, width, height,
|
||||
stride, pixel_format, transform_flags, crop_rect};
|
||||
|
||||
system.GetPerfStats().EndSystemFrame();
|
||||
system.GPU().SwapBuffers(&framebuffer);
|
||||
|
||||
@@ -111,7 +111,6 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
|
||||
event.event->GetWritableEvent().Signal();
|
||||
return NvResult::Success;
|
||||
}
|
||||
auto lock = gpu.LockSync();
|
||||
const u32 current_syncpoint_value = event.fence.value;
|
||||
const s32 diff = current_syncpoint_value - params.threshold;
|
||||
if (diff >= 0) {
|
||||
@@ -132,23 +131,24 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
|
||||
}
|
||||
|
||||
EventState status = events_interface.status[event_id];
|
||||
if (event_id < MaxNvEvents || status == EventState::Free || status == EventState::Registered) {
|
||||
events_interface.SetEventStatus(event_id, EventState::Waiting);
|
||||
events_interface.assigned_syncpt[event_id] = params.syncpt_id;
|
||||
events_interface.assigned_value[event_id] = target_value;
|
||||
if (is_async) {
|
||||
params.value = params.syncpt_id << 4;
|
||||
} else {
|
||||
params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000;
|
||||
}
|
||||
params.value |= event_id;
|
||||
event.event->GetWritableEvent().Clear();
|
||||
gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
|
||||
const bool bad_parameter = status != EventState::Free && status != EventState::Registered;
|
||||
if (bad_parameter) {
|
||||
std::memcpy(output.data(), ¶ms, sizeof(params));
|
||||
return NvResult::Timeout;
|
||||
return NvResult::BadParameter;
|
||||
}
|
||||
events_interface.SetEventStatus(event_id, EventState::Waiting);
|
||||
events_interface.assigned_syncpt[event_id] = params.syncpt_id;
|
||||
events_interface.assigned_value[event_id] = target_value;
|
||||
if (is_async) {
|
||||
params.value = params.syncpt_id << 4;
|
||||
} else {
|
||||
params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000;
|
||||
}
|
||||
params.value |= event_id;
|
||||
event.event->GetWritableEvent().Clear();
|
||||
gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
|
||||
std::memcpy(output.data(), ¶ms, sizeof(params));
|
||||
return NvResult::BadParameter;
|
||||
return NvResult::Timeout;
|
||||
}
|
||||
|
||||
NvResult nvhost_ctrl::IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
|
||||
@@ -13,6 +13,14 @@
|
||||
#include "video_core/memory_manager.h"
|
||||
|
||||
namespace Service::Nvidia::Devices {
|
||||
namespace {
|
||||
Tegra::CommandHeader BuildFenceAction(Tegra::GPU::FenceOperation op, u32 syncpoint_id) {
|
||||
Tegra::GPU::FenceAction result{};
|
||||
result.op.Assign(op);
|
||||
result.syncpoint_id.Assign(syncpoint_id);
|
||||
return {result.raw};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
nvhost_gpu::nvhost_gpu(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_,
|
||||
SyncpointManager& syncpoint_manager_)
|
||||
@@ -187,7 +195,7 @@ static std::vector<Tegra::CommandHeader> BuildWaitCommandList(Fence fence) {
|
||||
{fence.value},
|
||||
Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1,
|
||||
Tegra::SubmissionMode::Increasing),
|
||||
Tegra::GPU::FenceAction::Build(Tegra::GPU::FenceOperation::Acquire, fence.id),
|
||||
BuildFenceAction(Tegra::GPU::FenceOperation::Acquire, fence.id),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -200,8 +208,7 @@ static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(Fence fence,
|
||||
for (u32 count = 0; count < add_increment; ++count) {
|
||||
result.emplace_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1,
|
||||
Tegra::SubmissionMode::Increasing));
|
||||
result.emplace_back(
|
||||
Tegra::GPU::FenceAction::Build(Tegra::GPU::FenceOperation::Increment, fence.id));
|
||||
result.emplace_back(BuildFenceAction(Tegra::GPU::FenceOperation::Increment, fence.id));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -13,28 +13,20 @@
|
||||
#include "common/thread.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/core_timing_util.h"
|
||||
#include "core/hardware_properties.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
|
||||
#include "core/hle/service/nvdrv/nvdrv.h"
|
||||
#include "core/hle/service/nvflinger/buffer_queue.h"
|
||||
#include "core/hle/service/nvflinger/nvflinger.h"
|
||||
#include "core/hle/service/vi/display/vi_display.h"
|
||||
#include "core/hle/service/vi/layer/vi_layer.h"
|
||||
#include "core/perf_stats.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
#include "video_core/gpu.h"
|
||||
|
||||
namespace Service::NVFlinger {
|
||||
|
||||
constexpr auto frame_ns = std::chrono::nanoseconds{1000000000 / 60};
|
||||
|
||||
void NVFlinger::VSyncThread(NVFlinger& nv_flinger) {
|
||||
nv_flinger.SplitVSync();
|
||||
}
|
||||
|
||||
void NVFlinger::SplitVSync() {
|
||||
void NVFlinger::SplitVSync(std::stop_token stop_token) {
|
||||
system.RegisterHostThread();
|
||||
std::string name = "yuzu:VSyncThread";
|
||||
MicroProfileOnThreadCreate(name.c_str());
|
||||
@@ -45,7 +37,7 @@ void NVFlinger::SplitVSync() {
|
||||
Common::SetCurrentThreadName(name.c_str());
|
||||
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
|
||||
s64 delay = 0;
|
||||
while (is_running) {
|
||||
while (!stop_token.stop_requested()) {
|
||||
guard->lock();
|
||||
const s64 time_start = system.CoreTiming().GetGlobalTimeNs().count();
|
||||
Compose();
|
||||
@@ -55,7 +47,7 @@ void NVFlinger::SplitVSync() {
|
||||
const s64 next_time = std::max<s64>(0, ticks - time_passed - delay);
|
||||
guard->unlock();
|
||||
if (next_time > 0) {
|
||||
wait_event->WaitFor(std::chrono::nanoseconds{next_time});
|
||||
std::this_thread::sleep_for(std::chrono::nanoseconds{next_time});
|
||||
}
|
||||
delay = (system.CoreTiming().GetGlobalTimeNs().count() - time_end) - next_time;
|
||||
}
|
||||
@@ -84,9 +76,7 @@ NVFlinger::NVFlinger(Core::System& system_)
|
||||
});
|
||||
|
||||
if (system.IsMulticore()) {
|
||||
is_running = true;
|
||||
wait_event = std::make_unique<Common::Event>();
|
||||
vsync_thread = std::make_unique<std::thread>(VSyncThread, std::ref(*this));
|
||||
vsync_thread = std::jthread([this](std::stop_token token) { SplitVSync(token); });
|
||||
} else {
|
||||
system.CoreTiming().ScheduleEvent(frame_ns, composition_event);
|
||||
}
|
||||
@@ -96,14 +86,7 @@ NVFlinger::~NVFlinger() {
|
||||
for (auto& buffer_queue : buffer_queues) {
|
||||
buffer_queue->Disconnect();
|
||||
}
|
||||
|
||||
if (system.IsMulticore()) {
|
||||
is_running = false;
|
||||
wait_event->Set();
|
||||
vsync_thread->join();
|
||||
vsync_thread.reset();
|
||||
wait_event.reset();
|
||||
} else {
|
||||
if (!system.IsMulticore()) {
|
||||
system.CoreTiming().UnscheduleEvent(composition_event, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
@@ -109,9 +106,7 @@ private:
|
||||
/// Creates a layer with the specified layer ID in the desired display.
|
||||
void CreateLayerAtId(VI::Display& display, u64 layer_id);
|
||||
|
||||
static void VSyncThread(NVFlinger& nv_flinger);
|
||||
|
||||
void SplitVSync();
|
||||
void SplitVSync(std::stop_token stop_token);
|
||||
|
||||
std::shared_ptr<Nvidia::Module> nvdrv;
|
||||
|
||||
@@ -133,9 +128,7 @@ private:
|
||||
|
||||
Core::System& system;
|
||||
|
||||
std::unique_ptr<std::thread> vsync_thread;
|
||||
std::unique_ptr<Common::Event> wait_event;
|
||||
std::atomic<bool> is_running{};
|
||||
std::jthread vsync_thread;
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
};
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/olsc/olsc.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
|
||||
@@ -8,9 +8,8 @@
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/k_writable_event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/ptm/psm.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
@@ -20,7 +19,7 @@ namespace Service::PSM {
|
||||
class IPsmSession final : public ServiceFramework<IPsmSession> {
|
||||
public:
|
||||
explicit IPsmSession(Core::System& system_)
|
||||
: ServiceFramework{system_, "IPsmSession"}, state_change_event{system.Kernel()} {
|
||||
: ServiceFramework{system_, "IPsmSession"}, service_context{system_, "IPsmSession"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IPsmSession::BindStateChangeEvent, "BindStateChangeEvent"},
|
||||
@@ -33,27 +32,28 @@ public:
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
Kernel::KAutoObject::Create(std::addressof(state_change_event));
|
||||
state_change_event.Initialize("IPsmSession::state_change_event");
|
||||
state_change_event = service_context.CreateEvent("IPsmSession::state_change_event");
|
||||
}
|
||||
|
||||
~IPsmSession() override = default;
|
||||
~IPsmSession() override {
|
||||
service_context.CloseEvent(state_change_event);
|
||||
}
|
||||
|
||||
void SignalChargerTypeChanged() {
|
||||
if (should_signal && should_signal_charger_type) {
|
||||
state_change_event.GetWritableEvent().Signal();
|
||||
state_change_event->GetWritableEvent().Signal();
|
||||
}
|
||||
}
|
||||
|
||||
void SignalPowerSupplyChanged() {
|
||||
if (should_signal && should_signal_power_supply) {
|
||||
state_change_event.GetWritableEvent().Signal();
|
||||
state_change_event->GetWritableEvent().Signal();
|
||||
}
|
||||
}
|
||||
|
||||
void SignalBatteryVoltageStateChanged() {
|
||||
if (should_signal && should_signal_battery_voltage) {
|
||||
state_change_event.GetWritableEvent().Signal();
|
||||
state_change_event->GetWritableEvent().Signal();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushCopyObjects(state_change_event.GetReadableEvent());
|
||||
rb.PushCopyObjects(state_change_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void UnbindStateChangeEvent(Kernel::HLERequestContext& ctx) {
|
||||
@@ -110,11 +110,13 @@ private:
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
bool should_signal_charger_type{};
|
||||
bool should_signal_power_supply{};
|
||||
bool should_signal_battery_voltage{};
|
||||
bool should_signal{};
|
||||
Kernel::KEvent state_change_event;
|
||||
Kernel::KEvent* state_change_event;
|
||||
};
|
||||
|
||||
class PSM final : public ServiceFramework<PSM> {
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "core/file_sys/errors.h"
|
||||
#include "core/file_sys/system_archive/system_version.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_client_port.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/hle/service/set/set_sys.h"
|
||||
|
||||
|
||||
@@ -5,11 +5,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/sockets/sockets.h"
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
@@ -4,13 +4,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::SM {
|
||||
class ServiceManager;
|
||||
}
|
||||
|
||||
namespace Service::Sockets {
|
||||
|
||||
enum class Errno : u32 {
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
#include "core/hle/service/ssl/ssl.h"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/time/standard_local_system_clock_core.h"
|
||||
#include "core/hle/service/time/standard_network_system_clock_core.h"
|
||||
#include "core/hle/service/time/standard_user_system_clock_core.h"
|
||||
@@ -16,10 +17,15 @@ StandardUserSystemClockCore::StandardUserSystemClockCore(
|
||||
: SystemClockCore(local_system_clock_core_.GetSteadyClockCore()),
|
||||
local_system_clock_core{local_system_clock_core_},
|
||||
network_system_clock_core{network_system_clock_core_},
|
||||
auto_correction_time{SteadyClockTimePoint::GetRandom()}, auto_correction_event{
|
||||
system_.Kernel()} {
|
||||
Kernel::KAutoObject::Create(std::addressof(auto_correction_event));
|
||||
auto_correction_event.Initialize("StandardUserSystemClockCore:AutoCorrectionEvent");
|
||||
auto_correction_time{SteadyClockTimePoint::GetRandom()}, service_context{
|
||||
system_,
|
||||
"StandardUserSystemClockCore"} {
|
||||
auto_correction_event =
|
||||
service_context.CreateEvent("StandardUserSystemClockCore:AutoCorrectionEvent");
|
||||
}
|
||||
|
||||
StandardUserSystemClockCore::~StandardUserSystemClockCore() {
|
||||
service_context.CloseEvent(auto_correction_event);
|
||||
}
|
||||
|
||||
ResultCode StandardUserSystemClockCore::SetAutomaticCorrectionEnabled(Core::System& system,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/time/clock_types.h"
|
||||
#include "core/hle/service/time/system_clock_core.h"
|
||||
|
||||
@@ -27,6 +27,8 @@ public:
|
||||
StandardNetworkSystemClockCore& network_system_clock_core_,
|
||||
Core::System& system_);
|
||||
|
||||
~StandardUserSystemClockCore() override;
|
||||
|
||||
ResultCode SetAutomaticCorrectionEnabled(Core::System& system, bool value);
|
||||
|
||||
ResultCode GetClockContext(Core::System& system, SystemClockContext& ctx) const override;
|
||||
@@ -55,7 +57,8 @@ private:
|
||||
StandardNetworkSystemClockCore& network_system_clock_core;
|
||||
bool auto_correction_enabled{};
|
||||
SteadyClockTimePoint auto_correction_time;
|
||||
Kernel::KEvent auto_correction_event;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
Kernel::KEvent* auto_correction_event;
|
||||
};
|
||||
|
||||
} // namespace Service::Time::Clock
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "core/hle/service/time/clock_types.h"
|
||||
|
||||
@@ -13,7 +13,7 @@ SystemClockCore::SystemClockCore(SteadyClockCore& steady_clock_core_)
|
||||
context.steady_time_point.clock_source_id = steady_clock_core.GetClockSourceId();
|
||||
}
|
||||
|
||||
SystemClockCore ::~SystemClockCore() = default;
|
||||
SystemClockCore::~SystemClockCore() = default;
|
||||
|
||||
ResultCode SystemClockCore::GetCurrentTime(Core::System& system, s64& posix_time) const {
|
||||
posix_time = 0;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/service/time/clock_types.h"
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
#include "core/core_timing_util.h"
|
||||
#include "core/hardware_properties.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_client_port.h"
|
||||
#include "core/hle/kernel/k_scheduler.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/time/time.h"
|
||||
#include "core/hle/service/time/time_interface.h"
|
||||
#include "core/hle/service/time/time_manager.h"
|
||||
#include "core/hle/service/time/time_sharedmemory.h"
|
||||
#include "core/hle/service/time/time_zone_service.h"
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/time/clock_types.h"
|
||||
#include "core/hle/service/time/time_manager.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
namespace Service::Time {
|
||||
|
||||
ITimeZoneService ::ITimeZoneService(Core::System& system_,
|
||||
TimeZone::TimeZoneContentManager& time_zone_manager_)
|
||||
ITimeZoneService::ITimeZoneService(Core::System& system_,
|
||||
TimeZone::TimeZoneContentManager& time_zone_manager_)
|
||||
: ServiceFramework{system_, "ITimeZoneService"}, time_zone_content_manager{time_zone_manager_} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ITimeZoneService::GetDeviceLocationName, "GetDeviceLocationName"},
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
#include "core/hle/service/usb/usb.h"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
+5
-1
@@ -587,7 +587,11 @@ void Memory::UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) {
|
||||
bool Memory::IsValidVirtualAddress(const VAddr vaddr) const {
|
||||
const Kernel::KProcess& process = *system.CurrentProcess();
|
||||
const auto& page_table = process.PageTable().PageTableImpl();
|
||||
const auto [pointer, type] = page_table.pointers[vaddr >> PAGE_BITS].PointerType();
|
||||
const size_t page = vaddr >> PAGE_BITS;
|
||||
if (page >= page_table.pointers.size()) {
|
||||
return false;
|
||||
}
|
||||
const auto [pointer, type] = page_table.pointers[page].PointerType();
|
||||
return pointer != nullptr || type == Common::PageType::RasterizerCachedMemory;
|
||||
}
|
||||
|
||||
|
||||
@@ -366,8 +366,6 @@ std::optional<IPv4Address> GetHostIPv4Address() {
|
||||
if (res != network_interfaces.end()) {
|
||||
char ip_addr[16] = {};
|
||||
ASSERT(inet_ntop(AF_INET, &res->ip_address, ip_addr, sizeof(ip_addr)) != nullptr);
|
||||
LOG_INFO(Network, "IP address: {}", ip_addr);
|
||||
|
||||
return TranslateIPv4(res->ip_address);
|
||||
} else {
|
||||
LOG_ERROR(Network, "Couldn't find selected interface \"{}\"", selected_network_interface);
|
||||
|
||||
@@ -32,6 +32,30 @@ void Mouse::UpdateThread(std::stop_token stop_token) {
|
||||
info.tilt_speed = 0;
|
||||
info.data.motion = info.motion.GetMotion();
|
||||
if (Settings::values.mouse_panning) {
|
||||
if (Settings::values.mouse_as_joystick) {
|
||||
float axis_x = 0.0f;
|
||||
float axis_y = 0.0f;
|
||||
const float max_mouse_movement =
|
||||
static_cast<float>(Settings::values.max_mouse_movement.GetValue());
|
||||
const float deadzone = Settings::values.mouse_as_joystick_deadzone.GetValue() /
|
||||
100.0f * max_mouse_movement;
|
||||
if (fabs(info.last_mouse_change.x) > deadzone) {
|
||||
axis_x = info.last_mouse_change.x -
|
||||
(info.last_mouse_change.x > 0 ? deadzone : -deadzone);
|
||||
axis_x /= max_mouse_movement;
|
||||
axis_x *= 8;
|
||||
}
|
||||
|
||||
if (fabs(info.last_mouse_change.y) > deadzone) {
|
||||
axis_y = info.last_mouse_change.y -
|
||||
(info.last_mouse_change.y > 0 ? deadzone : -deadzone);
|
||||
axis_y /= max_mouse_movement;
|
||||
axis_y *= 8;
|
||||
}
|
||||
info.data.axis = {static_cast<int>(16 * axis_x),
|
||||
static_cast<int>(16 * -axis_y)};
|
||||
continue;
|
||||
}
|
||||
info.last_mouse_change *= 0.96f;
|
||||
info.data.axis = {static_cast<int>(16 * info.last_mouse_change.x),
|
||||
static_cast<int>(16 * -info.last_mouse_change.y)};
|
||||
@@ -40,8 +64,10 @@ void Mouse::UpdateThread(std::stop_token stop_token) {
|
||||
if (configuring) {
|
||||
UpdateYuzuSettings();
|
||||
}
|
||||
if (mouse_panning_timout++ > 20) {
|
||||
StopPanning();
|
||||
if (!Settings::values.mouse_as_joystick) {
|
||||
if (mouse_panning_timout++ > 20) {
|
||||
StopPanning();
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(update_time));
|
||||
}
|
||||
@@ -92,6 +118,19 @@ void Mouse::MouseMove(int x, int y, int center_x, int center_y) {
|
||||
if (mouse_change.y == 0 && mouse_change.x == 0) {
|
||||
continue;
|
||||
}
|
||||
if (Settings::values.mouse_as_joystick) {
|
||||
info.last_mouse_change += mouse_change;
|
||||
|
||||
const float max_mouse_movement =
|
||||
static_cast<float>(Settings::values.max_mouse_movement.GetValue());
|
||||
info.last_mouse_change = {
|
||||
std::clamp(info.last_mouse_change.x, -max_mouse_movement, max_mouse_movement),
|
||||
std::clamp(info.last_mouse_change.y, -max_mouse_movement, max_mouse_movement)};
|
||||
|
||||
info.tilt_direction = info.last_mouse_change;
|
||||
info.tilt_speed = info.tilt_direction.Normalize() * info.sensitivity;
|
||||
continue;
|
||||
}
|
||||
const auto mouse_change_length = mouse_change.Length();
|
||||
if (mouse_change_length < 3.0f) {
|
||||
mouse_change /= mouse_change_length / 3.0f;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <mutex>
|
||||
#include <stop_token>
|
||||
|
||||
@@ -254,11 +254,25 @@ public:
|
||||
}
|
||||
|
||||
bool IsJoyconLeft() const {
|
||||
return std::strstr(GetControllerName().c_str(), "Joy-Con Left") != nullptr;
|
||||
const std::string controller_name = GetControllerName();
|
||||
if (std::strstr(controller_name.c_str(), "Joy-Con Left") != nullptr) {
|
||||
return true;
|
||||
}
|
||||
if (std::strstr(controller_name.c_str(), "Joy-Con (L)") != nullptr) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsJoyconRight() const {
|
||||
return std::strstr(GetControllerName().c_str(), "Joy-Con Right") != nullptr;
|
||||
const std::string controller_name = GetControllerName();
|
||||
if (std::strstr(controller_name.c_str(), "Joy-Con Right") != nullptr) {
|
||||
return true;
|
||||
}
|
||||
if (std::strstr(controller_name.c_str(), "Joy-Con (R)") != nullptr) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string GetControllerName() const {
|
||||
|
||||
@@ -58,8 +58,8 @@ void GetCbuf(EmitContext& ctx, std::string_view ret, const IR::Value& binding,
|
||||
const auto cbuf{fmt::format("{}_cbuf{}", ctx.stage_name, binding.U32())};
|
||||
const auto cbuf_cast{fmt::format("{}({}[{}]{{}})", cast, cbuf, index)};
|
||||
const auto extraction{num_bits == 32 ? cbuf_cast
|
||||
: fmt ::format("bitfieldExtract({},int({}),{})", cbuf_cast,
|
||||
bit_offset, num_bits)};
|
||||
: fmt::format("bitfieldExtract({},int({}),{})", cbuf_cast,
|
||||
bit_offset, num_bits)};
|
||||
if (!component_indexing_bug) {
|
||||
const auto result{fmt::format(fmt::runtime(extraction), swizzle)};
|
||||
ctx.Add("{}={};", ret, result);
|
||||
|
||||
@@ -570,13 +570,12 @@ bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am
|
||||
ForEachWrittenRange(*cpu_src_address, amount, mirror);
|
||||
// This subtraction in this order is important for overlapping copies.
|
||||
common_ranges.subtract(subtract_interval);
|
||||
bool atleast_1_download = tmp_intervals.size() != 0;
|
||||
for (const IntervalType add_interval : tmp_intervals) {
|
||||
const bool has_new_downloads = tmp_intervals.size() != 0;
|
||||
for (const IntervalType& add_interval : tmp_intervals) {
|
||||
common_ranges.add(add_interval);
|
||||
}
|
||||
|
||||
runtime.CopyBuffer(dest_buffer, src_buffer, copies);
|
||||
if (atleast_1_download) {
|
||||
if (has_new_downloads) {
|
||||
dest_buffer.MarkRegionAsGpuModified(*cpu_dest_address, amount);
|
||||
}
|
||||
std::vector<u8> tmp_buffer(amount);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "command_classes/vic.h"
|
||||
#include "video_core/cdma_pusher.h"
|
||||
#include "video_core/command_classes/nvdec_common.h"
|
||||
#include "video_core/command_classes/sync_manager.h"
|
||||
#include "video_core/engines/maxwell_3d.h"
|
||||
#include "video_core/gpu.h"
|
||||
#include "video_core/memory_manager.h"
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_types.h"
|
||||
#include "video_core/command_classes/sync_manager.h"
|
||||
|
||||
namespace Tegra {
|
||||
|
||||
class GPU;
|
||||
class Host1x;
|
||||
class Nvdec;
|
||||
class SyncptIncrManager;
|
||||
class Vic;
|
||||
|
||||
enum class ChSubmissionMode : u32 {
|
||||
|
||||
@@ -16,6 +16,7 @@ extern "C" {
|
||||
}
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/bit_field.h"
|
||||
#include "common/logging/log.h"
|
||||
|
||||
#include "video_core/command_classes/nvdec.h"
|
||||
@@ -26,6 +27,25 @@ extern "C" {
|
||||
#include "video_core/textures/decoders.h"
|
||||
|
||||
namespace Tegra {
|
||||
namespace {
|
||||
enum class VideoPixelFormat : u64_le {
|
||||
RGBA8 = 0x1f,
|
||||
BGRA8 = 0x20,
|
||||
RGBX8 = 0x23,
|
||||
Yuv420 = 0x44,
|
||||
};
|
||||
} // Anonymous namespace
|
||||
|
||||
union VicConfig {
|
||||
u64_le raw{};
|
||||
BitField<0, 7, VideoPixelFormat> pixel_format;
|
||||
BitField<7, 2, u64_le> chroma_loc_horiz;
|
||||
BitField<9, 2, u64_le> chroma_loc_vert;
|
||||
BitField<11, 4, u64_le> block_linear_kind;
|
||||
BitField<15, 4, u64_le> block_linear_height_log2;
|
||||
BitField<32, 14, u64_le> surface_width_minus1;
|
||||
BitField<46, 14, u64_le> surface_height_minus1;
|
||||
};
|
||||
|
||||
Vic::Vic(GPU& gpu_, std::shared_ptr<Nvdec> nvdec_processor_)
|
||||
: gpu(gpu_),
|
||||
@@ -65,134 +85,156 @@ void Vic::Execute() {
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
const auto pixel_format = static_cast<VideoPixelFormat>(config.pixel_format.Value());
|
||||
switch (pixel_format) {
|
||||
const u64 surface_width = config.surface_width_minus1 + 1;
|
||||
const u64 surface_height = config.surface_height_minus1 + 1;
|
||||
if (static_cast<u64>(frame->width) != surface_width ||
|
||||
static_cast<u64>(frame->height) > surface_height) {
|
||||
// TODO: Properly support multiple video streams with differing frame dimensions
|
||||
LOG_WARNING(Debug,
|
||||
"Frame dimensions {}x{} can't be safely decoded into surface dimensions {}x{}",
|
||||
frame->width, frame->height, surface_width, surface_height);
|
||||
return;
|
||||
}
|
||||
switch (config.pixel_format) {
|
||||
case VideoPixelFormat::RGBA8:
|
||||
case VideoPixelFormat::BGRA8:
|
||||
case VideoPixelFormat::RGBA8: {
|
||||
LOG_TRACE(Service_NVDRV, "Writing RGB Frame");
|
||||
|
||||
if (scaler_ctx == nullptr || frame->width != scaler_width ||
|
||||
frame->height != scaler_height) {
|
||||
const AVPixelFormat target_format =
|
||||
(pixel_format == VideoPixelFormat::RGBA8) ? AV_PIX_FMT_RGBA : AV_PIX_FMT_BGRA;
|
||||
|
||||
sws_freeContext(scaler_ctx);
|
||||
scaler_ctx = nullptr;
|
||||
|
||||
// Frames are decoded into either YUV420 or NV12 formats. Convert to desired format
|
||||
scaler_ctx = sws_getContext(frame->width, frame->height,
|
||||
static_cast<AVPixelFormat>(frame->format), frame->width,
|
||||
frame->height, target_format, 0, nullptr, nullptr, nullptr);
|
||||
|
||||
scaler_width = frame->width;
|
||||
scaler_height = frame->height;
|
||||
}
|
||||
// Get Converted frame
|
||||
const u32 width = static_cast<u32>(frame->width);
|
||||
const u32 height = static_cast<u32>(frame->height);
|
||||
const std::size_t linear_size = width * height * 4;
|
||||
|
||||
// Only allocate frame_buffer once per stream, as the size is not expected to change
|
||||
if (!converted_frame_buffer) {
|
||||
converted_frame_buffer = AVMallocPtr{static_cast<u8*>(av_malloc(linear_size)), av_free};
|
||||
}
|
||||
const std::array<int, 4> converted_stride{frame->width * 4, frame->height * 4, 0, 0};
|
||||
u8* const converted_frame_buf_addr{converted_frame_buffer.get()};
|
||||
|
||||
sws_scale(scaler_ctx, frame->data, frame->linesize, 0, frame->height,
|
||||
&converted_frame_buf_addr, converted_stride.data());
|
||||
|
||||
const u32 blk_kind = static_cast<u32>(config.block_linear_kind);
|
||||
if (blk_kind != 0) {
|
||||
// swizzle pitch linear to block linear
|
||||
const u32 block_height = static_cast<u32>(config.block_linear_height_log2);
|
||||
const auto size =
|
||||
Tegra::Texture::CalculateSize(true, 4, width, height, 1, block_height, 0);
|
||||
luma_buffer.resize(size);
|
||||
Tegra::Texture::SwizzleSubrect(width, height, width * 4, width, 4, luma_buffer.data(),
|
||||
converted_frame_buffer.get(), block_height, 0, 0);
|
||||
|
||||
gpu.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(), size);
|
||||
} else {
|
||||
// send pitch linear frame
|
||||
gpu.MemoryManager().WriteBlock(output_surface_luma_address, converted_frame_buf_addr,
|
||||
linear_size);
|
||||
}
|
||||
case VideoPixelFormat::RGBX8:
|
||||
WriteRGBFrame(frame, config);
|
||||
break;
|
||||
}
|
||||
case VideoPixelFormat::Yuv420: {
|
||||
LOG_TRACE(Service_NVDRV, "Writing YUV420 Frame");
|
||||
|
||||
const std::size_t surface_width = config.surface_width_minus1 + 1;
|
||||
const std::size_t surface_height = config.surface_height_minus1 + 1;
|
||||
const auto frame_width = std::min(surface_width, static_cast<size_t>(frame->width));
|
||||
const auto frame_height = std::min(surface_height, static_cast<size_t>(frame->height));
|
||||
const std::size_t aligned_width = (surface_width + 0xff) & ~0xffUL;
|
||||
|
||||
const auto stride = static_cast<size_t>(frame->linesize[0]);
|
||||
|
||||
luma_buffer.resize(aligned_width * surface_height);
|
||||
chroma_buffer.resize(aligned_width * surface_height / 2);
|
||||
|
||||
// Populate luma buffer
|
||||
const u8* luma_src = frame->data[0];
|
||||
for (std::size_t y = 0; y < frame_height; ++y) {
|
||||
const std::size_t src = y * stride;
|
||||
const std::size_t dst = y * aligned_width;
|
||||
for (std::size_t x = 0; x < frame_width; ++x) {
|
||||
luma_buffer[dst + x] = luma_src[src + x];
|
||||
}
|
||||
}
|
||||
gpu.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(),
|
||||
luma_buffer.size());
|
||||
|
||||
// Chroma
|
||||
const std::size_t half_height = frame_height / 2;
|
||||
const auto half_stride = static_cast<size_t>(frame->linesize[1]);
|
||||
|
||||
switch (frame->format) {
|
||||
case AV_PIX_FMT_YUV420P: {
|
||||
// Frame from FFmpeg software
|
||||
// Populate chroma buffer from both channels with interleaving.
|
||||
const std::size_t half_width = frame_width / 2;
|
||||
const u8* chroma_b_src = frame->data[1];
|
||||
const u8* chroma_r_src = frame->data[2];
|
||||
for (std::size_t y = 0; y < half_height; ++y) {
|
||||
const std::size_t src = y * half_stride;
|
||||
const std::size_t dst = y * aligned_width;
|
||||
|
||||
for (std::size_t x = 0; x < half_width; ++x) {
|
||||
chroma_buffer[dst + x * 2] = chroma_b_src[src + x];
|
||||
chroma_buffer[dst + x * 2 + 1] = chroma_r_src[src + x];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AV_PIX_FMT_NV12: {
|
||||
// Frame from VA-API hardware
|
||||
// This is already interleaved so just copy
|
||||
const u8* chroma_src = frame->data[1];
|
||||
for (std::size_t y = 0; y < half_height; ++y) {
|
||||
const std::size_t src = y * stride;
|
||||
const std::size_t dst = y * aligned_width;
|
||||
for (std::size_t x = 0; x < frame_width; ++x) {
|
||||
chroma_buffer[dst + x] = chroma_src[src + x];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
gpu.MemoryManager().WriteBlock(output_surface_chroma_address, chroma_buffer.data(),
|
||||
chroma_buffer.size());
|
||||
case VideoPixelFormat::Yuv420:
|
||||
WriteYUVFrame(frame, config);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unknown video pixel format {}", config.pixel_format.Value());
|
||||
UNIMPLEMENTED_MSG("Unknown video pixel format {:X}", config.pixel_format.Value());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Vic::WriteRGBFrame(const AVFrame* frame, const VicConfig& config) {
|
||||
LOG_TRACE(Service_NVDRV, "Writing RGB Frame");
|
||||
|
||||
if (!scaler_ctx || frame->width != scaler_width || frame->height != scaler_height) {
|
||||
const AVPixelFormat target_format = [pixel_format = config.pixel_format]() {
|
||||
switch (pixel_format) {
|
||||
case VideoPixelFormat::RGBA8:
|
||||
return AV_PIX_FMT_RGBA;
|
||||
case VideoPixelFormat::BGRA8:
|
||||
return AV_PIX_FMT_BGRA;
|
||||
case VideoPixelFormat::RGBX8:
|
||||
return AV_PIX_FMT_RGB0;
|
||||
default:
|
||||
return AV_PIX_FMT_RGBA;
|
||||
}
|
||||
}();
|
||||
|
||||
sws_freeContext(scaler_ctx);
|
||||
// Frames are decoded into either YUV420 or NV12 formats. Convert to desired RGB format
|
||||
scaler_ctx = sws_getContext(frame->width, frame->height,
|
||||
static_cast<AVPixelFormat>(frame->format), frame->width,
|
||||
frame->height, target_format, 0, nullptr, nullptr, nullptr);
|
||||
scaler_width = frame->width;
|
||||
scaler_height = frame->height;
|
||||
converted_frame_buffer.reset();
|
||||
}
|
||||
// Get Converted frame
|
||||
const u32 width = static_cast<u32>(frame->width);
|
||||
const u32 height = static_cast<u32>(frame->height);
|
||||
const std::size_t linear_size = width * height * 4;
|
||||
|
||||
// Only allocate frame_buffer once per stream, as the size is not expected to change
|
||||
if (!converted_frame_buffer) {
|
||||
converted_frame_buffer = AVMallocPtr{static_cast<u8*>(av_malloc(linear_size)), av_free};
|
||||
}
|
||||
const std::array<int, 4> converted_stride{frame->width * 4, frame->height * 4, 0, 0};
|
||||
u8* const converted_frame_buf_addr{converted_frame_buffer.get()};
|
||||
|
||||
sws_scale(scaler_ctx, frame->data, frame->linesize, 0, frame->height, &converted_frame_buf_addr,
|
||||
converted_stride.data());
|
||||
|
||||
const u32 blk_kind = static_cast<u32>(config.block_linear_kind);
|
||||
if (blk_kind != 0) {
|
||||
// swizzle pitch linear to block linear
|
||||
const u32 block_height = static_cast<u32>(config.block_linear_height_log2);
|
||||
const auto size = Texture::CalculateSize(true, 4, width, height, 1, block_height, 0);
|
||||
luma_buffer.resize(size);
|
||||
Texture::SwizzleSubrect(width, height, width * 4, width, 4, luma_buffer.data(),
|
||||
converted_frame_buffer.get(), block_height, 0, 0);
|
||||
|
||||
gpu.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(), size);
|
||||
} else {
|
||||
// send pitch linear frame
|
||||
gpu.MemoryManager().WriteBlock(output_surface_luma_address, converted_frame_buf_addr,
|
||||
linear_size);
|
||||
}
|
||||
}
|
||||
|
||||
void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
|
||||
LOG_TRACE(Service_NVDRV, "Writing YUV420 Frame");
|
||||
|
||||
const std::size_t surface_width = config.surface_width_minus1 + 1;
|
||||
const std::size_t surface_height = config.surface_height_minus1 + 1;
|
||||
const auto frame_width = std::min(surface_width, static_cast<size_t>(frame->width));
|
||||
const auto frame_height = std::min(surface_height, static_cast<size_t>(frame->height));
|
||||
const std::size_t aligned_width = (surface_width + 0xff) & ~0xffUL;
|
||||
|
||||
const auto stride = static_cast<size_t>(frame->linesize[0]);
|
||||
|
||||
luma_buffer.resize(aligned_width * surface_height);
|
||||
chroma_buffer.resize(aligned_width * surface_height / 2);
|
||||
|
||||
// Populate luma buffer
|
||||
const u8* luma_src = frame->data[0];
|
||||
for (std::size_t y = 0; y < frame_height; ++y) {
|
||||
const std::size_t src = y * stride;
|
||||
const std::size_t dst = y * aligned_width;
|
||||
for (std::size_t x = 0; x < frame_width; ++x) {
|
||||
luma_buffer[dst + x] = luma_src[src + x];
|
||||
}
|
||||
}
|
||||
gpu.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(),
|
||||
luma_buffer.size());
|
||||
|
||||
// Chroma
|
||||
const std::size_t half_height = frame_height / 2;
|
||||
const auto half_stride = static_cast<size_t>(frame->linesize[1]);
|
||||
|
||||
switch (frame->format) {
|
||||
case AV_PIX_FMT_YUV420P: {
|
||||
// Frame from FFmpeg software
|
||||
// Populate chroma buffer from both channels with interleaving.
|
||||
const std::size_t half_width = frame_width / 2;
|
||||
const u8* chroma_b_src = frame->data[1];
|
||||
const u8* chroma_r_src = frame->data[2];
|
||||
for (std::size_t y = 0; y < half_height; ++y) {
|
||||
const std::size_t src = y * half_stride;
|
||||
const std::size_t dst = y * aligned_width;
|
||||
|
||||
for (std::size_t x = 0; x < half_width; ++x) {
|
||||
chroma_buffer[dst + x * 2] = chroma_b_src[src + x];
|
||||
chroma_buffer[dst + x * 2 + 1] = chroma_r_src[src + x];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AV_PIX_FMT_NV12: {
|
||||
// Frame from VA-API hardware
|
||||
// This is already interleaved so just copy
|
||||
const u8* chroma_src = frame->data[1];
|
||||
for (std::size_t y = 0; y < half_height; ++y) {
|
||||
const std::size_t src = y * stride;
|
||||
const std::size_t dst = y * aligned_width;
|
||||
for (std::size_t x = 0; x < frame_width; ++x) {
|
||||
chroma_buffer[dst + x] = chroma_src[src + x];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
gpu.MemoryManager().WriteBlock(output_surface_chroma_address, chroma_buffer.data(),
|
||||
chroma_buffer.size());
|
||||
}
|
||||
|
||||
} // namespace Tegra
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user