diff options
237 files changed, 5746 insertions, 3915 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/input/model/PlayerInput.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/input/model/PlayerInput.kt index d35de80c4..a84ac77a2 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/input/model/PlayerInput.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/input/model/PlayerInput.kt | |||
| @@ -64,17 +64,17 @@ data class PlayerInput( | |||
| 64 | fun hasMapping(): Boolean { | 64 | fun hasMapping(): Boolean { |
| 65 | var hasMapping = false | 65 | var hasMapping = false |
| 66 | buttons.forEach { | 66 | buttons.forEach { |
| 67 | if (it != "[empty]") { | 67 | if (it != "[empty]" && it.isNotEmpty()) { |
| 68 | hasMapping = true | 68 | hasMapping = true |
| 69 | } | 69 | } |
| 70 | } | 70 | } |
| 71 | analogs.forEach { | 71 | analogs.forEach { |
| 72 | if (it != "[empty]") { | 72 | if (it != "[empty]" && it.isNotEmpty()) { |
| 73 | hasMapping = true | 73 | hasMapping = true |
| 74 | } | 74 | } |
| 75 | } | 75 | } |
| 76 | motions.forEach { | 76 | motions.forEach { |
| 77 | if (it != "[empty]") { | 77 | if (it != "[empty]" && it.isNotEmpty()) { |
| 78 | hasMapping = true | 78 | hasMapping = true |
| 79 | } | 79 | } |
| 80 | } | 80 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/StringSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/StringSetting.kt index a0d8cfede..6f16cf5b1 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/StringSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/StringSetting.kt | |||
| @@ -6,7 +6,8 @@ package org.yuzu.yuzu_emu.features.settings.model | |||
| 6 | import org.yuzu.yuzu_emu.utils.NativeConfig | 6 | import org.yuzu.yuzu_emu.utils.NativeConfig |
| 7 | 7 | ||
| 8 | enum class StringSetting(override val key: String) : AbstractStringSetting { | 8 | enum class StringSetting(override val key: String) : AbstractStringSetting { |
| 9 | DRIVER_PATH("driver_path"); | 9 | DRIVER_PATH("driver_path"), |
| 10 | DEVICE_NAME("device_name"); | ||
| 10 | 11 | ||
| 11 | override fun getString(needsGlobal: Boolean): String = NativeConfig.getString(key, needsGlobal) | 12 | override fun getString(needsGlobal: Boolean): String = NativeConfig.getString(key, needsGlobal) |
| 12 | 13 | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index 8f724835e..5fdf98318 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt | |||
| @@ -16,6 +16,7 @@ import org.yuzu.yuzu_emu.features.settings.model.ByteSetting | |||
| 16 | import org.yuzu.yuzu_emu.features.settings.model.IntSetting | 16 | import org.yuzu.yuzu_emu.features.settings.model.IntSetting |
| 17 | import org.yuzu.yuzu_emu.features.settings.model.LongSetting | 17 | import org.yuzu.yuzu_emu.features.settings.model.LongSetting |
| 18 | import org.yuzu.yuzu_emu.features.settings.model.ShortSetting | 18 | import org.yuzu.yuzu_emu.features.settings.model.ShortSetting |
| 19 | import org.yuzu.yuzu_emu.features.settings.model.StringSetting | ||
| 19 | import org.yuzu.yuzu_emu.utils.NativeConfig | 20 | import org.yuzu.yuzu_emu.utils.NativeConfig |
| 20 | 21 | ||
| 21 | /** | 22 | /** |
| @@ -75,6 +76,9 @@ abstract class SettingsItem( | |||
| 75 | get() = NativeLibrary.isRunning() && !setting.global && | 76 | get() = NativeLibrary.isRunning() && !setting.global && |
| 76 | !NativeConfig.isPerGameConfigLoaded() | 77 | !NativeConfig.isPerGameConfigLoaded() |
| 77 | 78 | ||
| 79 | val clearable: Boolean | ||
| 80 | get() = !setting.global && NativeConfig.isPerGameConfigLoaded() | ||
| 81 | |||
| 78 | companion object { | 82 | companion object { |
| 79 | const val TYPE_HEADER = 0 | 83 | const val TYPE_HEADER = 0 |
| 80 | const val TYPE_SWITCH = 1 | 84 | const val TYPE_SWITCH = 1 |
| @@ -87,6 +91,7 @@ abstract class SettingsItem( | |||
| 87 | const val TYPE_INPUT = 8 | 91 | const val TYPE_INPUT = 8 |
| 88 | const val TYPE_INT_SINGLE_CHOICE = 9 | 92 | const val TYPE_INT_SINGLE_CHOICE = 9 |
| 89 | const val TYPE_INPUT_PROFILE = 10 | 93 | const val TYPE_INPUT_PROFILE = 10 |
| 94 | const val TYPE_STRING_INPUT = 11 | ||
| 90 | 95 | ||
| 91 | const val FASTMEM_COMBINED = "fastmem_combined" | 96 | const val FASTMEM_COMBINED = "fastmem_combined" |
| 92 | 97 | ||
| @@ -105,6 +110,7 @@ abstract class SettingsItem( | |||
| 105 | 110 | ||
| 106 | // List of all general | 111 | // List of all general |
| 107 | val settingsItems = HashMap<String, SettingsItem>().apply { | 112 | val settingsItems = HashMap<String, SettingsItem>().apply { |
| 113 | put(StringInputSetting(StringSetting.DEVICE_NAME, titleId = R.string.device_name)) | ||
| 108 | put( | 114 | put( |
| 109 | SwitchSetting( | 115 | SwitchSetting( |
| 110 | BooleanSetting.RENDERER_USE_SPEED_LIMIT, | 116 | BooleanSetting.RENDERER_USE_SPEED_LIMIT, |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/StringInputSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/StringInputSetting.kt new file mode 100644 index 000000000..1eb999416 --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/StringInputSetting.kt | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | package org.yuzu.yuzu_emu.features.settings.model.view | ||
| 5 | |||
| 6 | import androidx.annotation.StringRes | ||
| 7 | import org.yuzu.yuzu_emu.features.settings.model.AbstractStringSetting | ||
| 8 | |||
| 9 | class StringInputSetting( | ||
| 10 | setting: AbstractStringSetting, | ||
| 11 | @StringRes titleId: Int = 0, | ||
| 12 | titleString: String = "", | ||
| 13 | @StringRes descriptionId: Int = 0, | ||
| 14 | descriptionString: String = "" | ||
| 15 | ) : SettingsItem(setting, titleId, titleString, descriptionId, descriptionString) { | ||
| 16 | override val type = TYPE_STRING_INPUT | ||
| 17 | |||
| 18 | fun getSelectedValue(needsGlobal: Boolean = false) = setting.getValueAsString(needsGlobal) | ||
| 19 | |||
| 20 | fun setSelectedValue(selection: String) = | ||
| 21 | (setting as AbstractStringSetting).setString(selection) | ||
| 22 | } | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt index 45c8faa10..500ac6e66 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt | |||
| @@ -85,6 +85,10 @@ class SettingsAdapter( | |||
| 85 | InputProfileViewHolder(ListItemSettingBinding.inflate(inflater), this) | 85 | InputProfileViewHolder(ListItemSettingBinding.inflate(inflater), this) |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | SettingsItem.TYPE_STRING_INPUT -> { | ||
| 89 | StringInputViewHolder(ListItemSettingBinding.inflate(inflater), this) | ||
| 90 | } | ||
| 91 | |||
| 88 | else -> { | 92 | else -> { |
| 89 | HeaderViewHolder(ListItemSettingsHeaderBinding.inflate(inflater), this) | 93 | HeaderViewHolder(ListItemSettingsHeaderBinding.inflate(inflater), this) |
| 90 | } | 94 | } |
| @@ -392,6 +396,15 @@ class SettingsAdapter( | |||
| 392 | popup.show() | 396 | popup.show() |
| 393 | } | 397 | } |
| 394 | 398 | ||
| 399 | fun onStringInputClick(item: StringInputSetting, position: Int) { | ||
| 400 | SettingsDialogFragment.newInstance( | ||
| 401 | settingsViewModel, | ||
| 402 | item, | ||
| 403 | SettingsItem.TYPE_STRING_INPUT, | ||
| 404 | position | ||
| 405 | ).show(fragment.childFragmentManager, SettingsDialogFragment.TAG) | ||
| 406 | } | ||
| 407 | |||
| 395 | fun onLongClick(item: SettingsItem, position: Int): Boolean { | 408 | fun onLongClick(item: SettingsItem, position: Int): Boolean { |
| 396 | SettingsDialogFragment.newInstance( | 409 | SettingsDialogFragment.newInstance( |
| 397 | settingsViewModel, | 410 | settingsViewModel, |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsDialogFragment.kt index a81ff6b1a..7f562a1f4 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsDialogFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsDialogFragment.kt | |||
| @@ -14,6 +14,7 @@ import androidx.fragment.app.activityViewModels | |||
| 14 | import com.google.android.material.dialog.MaterialAlertDialogBuilder | 14 | import com.google.android.material.dialog.MaterialAlertDialogBuilder |
| 15 | import com.google.android.material.slider.Slider | 15 | import com.google.android.material.slider.Slider |
| 16 | import org.yuzu.yuzu_emu.R | 16 | import org.yuzu.yuzu_emu.R |
| 17 | import org.yuzu.yuzu_emu.databinding.DialogEditTextBinding | ||
| 17 | import org.yuzu.yuzu_emu.databinding.DialogSliderBinding | 18 | import org.yuzu.yuzu_emu.databinding.DialogSliderBinding |
| 18 | import org.yuzu.yuzu_emu.features.input.NativeInput | 19 | import org.yuzu.yuzu_emu.features.input.NativeInput |
| 19 | import org.yuzu.yuzu_emu.features.input.model.AnalogDirection | 20 | import org.yuzu.yuzu_emu.features.input.model.AnalogDirection |
| @@ -23,6 +24,7 @@ import org.yuzu.yuzu_emu.features.settings.model.view.IntSingleChoiceSetting | |||
| 23 | import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | 24 | import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem |
| 24 | import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting | 25 | import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting |
| 25 | import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting | 26 | import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting |
| 27 | import org.yuzu.yuzu_emu.features.settings.model.view.StringInputSetting | ||
| 26 | import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting | 28 | import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting |
| 27 | import org.yuzu.yuzu_emu.utils.ParamPackage | 29 | import org.yuzu.yuzu_emu.utils.ParamPackage |
| 28 | import org.yuzu.yuzu_emu.utils.collect | 30 | import org.yuzu.yuzu_emu.utils.collect |
| @@ -37,6 +39,7 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener | |||
| 37 | private val settingsViewModel: SettingsViewModel by activityViewModels() | 39 | private val settingsViewModel: SettingsViewModel by activityViewModels() |
| 38 | 40 | ||
| 39 | private lateinit var sliderBinding: DialogSliderBinding | 41 | private lateinit var sliderBinding: DialogSliderBinding |
| 42 | private lateinit var stringInputBinding: DialogEditTextBinding | ||
| 40 | 43 | ||
| 41 | override fun onCreate(savedInstanceState: Bundle?) { | 44 | override fun onCreate(savedInstanceState: Bundle?) { |
| 42 | super.onCreate(savedInstanceState) | 45 | super.onCreate(savedInstanceState) |
| @@ -131,6 +134,18 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener | |||
| 131 | .create() | 134 | .create() |
| 132 | } | 135 | } |
| 133 | 136 | ||
| 137 | SettingsItem.TYPE_STRING_INPUT -> { | ||
| 138 | stringInputBinding = DialogEditTextBinding.inflate(layoutInflater) | ||
| 139 | val item = settingsViewModel.clickedItem as StringInputSetting | ||
| 140 | stringInputBinding.editText.setText(item.getSelectedValue()) | ||
| 141 | MaterialAlertDialogBuilder(requireContext()) | ||
| 142 | .setTitle(item.title) | ||
| 143 | .setView(stringInputBinding.root) | ||
| 144 | .setPositiveButton(android.R.string.ok, this) | ||
| 145 | .setNegativeButton(android.R.string.cancel, defaultCancelListener) | ||
| 146 | .create() | ||
| 147 | } | ||
| 148 | |||
| 134 | SettingsItem.TYPE_STRING_SINGLE_CHOICE -> { | 149 | SettingsItem.TYPE_STRING_SINGLE_CHOICE -> { |
| 135 | val item = settingsViewModel.clickedItem as StringSingleChoiceSetting | 150 | val item = settingsViewModel.clickedItem as StringSingleChoiceSetting |
| 136 | MaterialAlertDialogBuilder(requireContext()) | 151 | MaterialAlertDialogBuilder(requireContext()) |
| @@ -158,6 +173,7 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener | |||
| 158 | ): View? { | 173 | ): View? { |
| 159 | return when (type) { | 174 | return when (type) { |
| 160 | SettingsItem.TYPE_SLIDER -> sliderBinding.root | 175 | SettingsItem.TYPE_SLIDER -> sliderBinding.root |
| 176 | SettingsItem.TYPE_STRING_INPUT -> stringInputBinding.root | ||
| 161 | else -> super.onCreateView(inflater, container, savedInstanceState) | 177 | else -> super.onCreateView(inflater, container, savedInstanceState) |
| 162 | } | 178 | } |
| 163 | } | 179 | } |
| @@ -200,6 +216,13 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener | |||
| 200 | val sliderSetting = settingsViewModel.clickedItem as SliderSetting | 216 | val sliderSetting = settingsViewModel.clickedItem as SliderSetting |
| 201 | sliderSetting.setSelectedValue(settingsViewModel.sliderProgress.value) | 217 | sliderSetting.setSelectedValue(settingsViewModel.sliderProgress.value) |
| 202 | } | 218 | } |
| 219 | |||
| 220 | is StringInputSetting -> { | ||
| 221 | val stringInputSetting = settingsViewModel.clickedItem as StringInputSetting | ||
| 222 | stringInputSetting.setSelectedValue( | ||
| 223 | (stringInputBinding.editText.text ?: "").toString() | ||
| 224 | ) | ||
| 225 | } | ||
| 203 | } | 226 | } |
| 204 | closeDialog() | 227 | closeDialog() |
| 205 | } | 228 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index e491c29a2..3ea5f5008 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt | |||
| @@ -23,6 +23,7 @@ import org.yuzu.yuzu_emu.features.settings.model.LongSetting | |||
| 23 | import org.yuzu.yuzu_emu.features.settings.model.Settings | 23 | import org.yuzu.yuzu_emu.features.settings.model.Settings |
| 24 | import org.yuzu.yuzu_emu.features.settings.model.Settings.MenuTag | 24 | import org.yuzu.yuzu_emu.features.settings.model.Settings.MenuTag |
| 25 | import org.yuzu.yuzu_emu.features.settings.model.ShortSetting | 25 | import org.yuzu.yuzu_emu.features.settings.model.ShortSetting |
| 26 | import org.yuzu.yuzu_emu.features.settings.model.StringSetting | ||
| 26 | import org.yuzu.yuzu_emu.features.settings.model.view.* | 27 | import org.yuzu.yuzu_emu.features.settings.model.view.* |
| 27 | import org.yuzu.yuzu_emu.utils.InputHandler | 28 | import org.yuzu.yuzu_emu.utils.InputHandler |
| 28 | import org.yuzu.yuzu_emu.utils.NativeConfig | 29 | import org.yuzu.yuzu_emu.utils.NativeConfig |
| @@ -153,6 +154,7 @@ class SettingsFragmentPresenter( | |||
| 153 | 154 | ||
| 154 | private fun addSystemSettings(sl: ArrayList<SettingsItem>) { | 155 | private fun addSystemSettings(sl: ArrayList<SettingsItem>) { |
| 155 | sl.apply { | 156 | sl.apply { |
| 157 | add(StringSetting.DEVICE_NAME.key) | ||
| 156 | add(BooleanSetting.RENDERER_USE_SPEED_LIMIT.key) | 158 | add(BooleanSetting.RENDERER_USE_SPEED_LIMIT.key) |
| 157 | add(ShortSetting.RENDERER_SPEED_LIMIT.key) | 159 | add(ShortSetting.RENDERER_SPEED_LIMIT.key) |
| 158 | add(BooleanSetting.USE_DOCKED_MODE.key) | 160 | add(BooleanSetting.USE_DOCKED_MODE.key) |
| @@ -778,7 +780,7 @@ class SettingsFragmentPresenter( | |||
| 778 | playerIndex: Int, | 780 | playerIndex: Int, |
| 779 | paramName: String, | 781 | paramName: String, |
| 780 | stick: NativeAnalog, | 782 | stick: NativeAnalog, |
| 781 | defaultValue: Int | 783 | defaultValue: Float |
| 782 | ): AbstractIntSetting = | 784 | ): AbstractIntSetting = |
| 783 | object : AbstractIntSetting { | 785 | object : AbstractIntSetting { |
| 784 | val params get() = NativeInput.getStickParam(playerIndex, stick) | 786 | val params get() = NativeInput.getStickParam(playerIndex, stick) |
| @@ -786,7 +788,7 @@ class SettingsFragmentPresenter( | |||
| 786 | override val key = "" | 788 | override val key = "" |
| 787 | 789 | ||
| 788 | override fun getInt(needsGlobal: Boolean): Int = | 790 | override fun getInt(needsGlobal: Boolean): Int = |
| 789 | (params.get(paramName, 0.15f) * 100).toInt() | 791 | (params.get(paramName, defaultValue) * 100).toInt() |
| 790 | 792 | ||
| 791 | override fun setInt(value: Int) { | 793 | override fun setInt(value: Int) { |
| 792 | val tempParams = params | 794 | val tempParams = params |
| @@ -794,12 +796,12 @@ class SettingsFragmentPresenter( | |||
| 794 | NativeInput.setStickParam(playerIndex, stick, tempParams) | 796 | NativeInput.setStickParam(playerIndex, stick, tempParams) |
| 795 | } | 797 | } |
| 796 | 798 | ||
| 797 | override val defaultValue = defaultValue | 799 | override val defaultValue = (defaultValue * 100).toInt() |
| 798 | 800 | ||
| 799 | override fun getValueAsString(needsGlobal: Boolean): String = | 801 | override fun getValueAsString(needsGlobal: Boolean): String = |
| 800 | getInt(needsGlobal).toString() | 802 | getInt(needsGlobal).toString() |
| 801 | 803 | ||
| 802 | override fun reset() = setInt(defaultValue) | 804 | override fun reset() = setInt(this.defaultValue) |
| 803 | } | 805 | } |
| 804 | 806 | ||
| 805 | private fun getExtraStickSettings( | 807 | private fun getExtraStickSettings( |
| @@ -809,11 +811,11 @@ class SettingsFragmentPresenter( | |||
| 809 | val stickIsController = | 811 | val stickIsController = |
| 810 | NativeInput.isController(NativeInput.getStickParam(playerIndex, nativeAnalog)) | 812 | NativeInput.isController(NativeInput.getStickParam(playerIndex, nativeAnalog)) |
| 811 | val modifierRangeSetting = | 813 | val modifierRangeSetting = |
| 812 | getStickIntSettingFromParam(playerIndex, "modifier_scale", nativeAnalog, 50) | 814 | getStickIntSettingFromParam(playerIndex, "modifier_scale", nativeAnalog, 0.5f) |
| 813 | val stickRangeSetting = | 815 | val stickRangeSetting = |
| 814 | getStickIntSettingFromParam(playerIndex, "range", nativeAnalog, 95) | 816 | getStickIntSettingFromParam(playerIndex, "range", nativeAnalog, 0.95f) |
| 815 | val stickDeadzoneSetting = | 817 | val stickDeadzoneSetting = |
| 816 | getStickIntSettingFromParam(playerIndex, "deadzone", nativeAnalog, 15) | 818 | getStickIntSettingFromParam(playerIndex, "deadzone", nativeAnalog, 0.15f) |
| 817 | 819 | ||
| 818 | val out = mutableListOf<SettingsItem>().apply { | 820 | val out = mutableListOf<SettingsItem>().apply { |
| 819 | if (stickIsController) { | 821 | if (stickIsController) { |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt index 367db7fd2..0309fad59 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt | |||
| @@ -13,7 +13,6 @@ import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding | |||
| 13 | import org.yuzu.yuzu_emu.features.settings.model.view.DateTimeSetting | 13 | import org.yuzu.yuzu_emu.features.settings.model.view.DateTimeSetting |
| 14 | import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | 14 | import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem |
| 15 | import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter | 15 | import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter |
| 16 | import org.yuzu.yuzu_emu.utils.NativeConfig | ||
| 17 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible | 16 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible |
| 18 | 17 | ||
| 19 | class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : | 18 | class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : |
| @@ -32,9 +31,7 @@ class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA | |||
| 32 | val dateFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM) | 31 | val dateFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM) |
| 33 | binding.textSettingValue.text = dateFormatter.format(zonedTime) | 32 | binding.textSettingValue.text = dateFormatter.format(zonedTime) |
| 34 | 33 | ||
| 35 | binding.buttonClear.setVisible( | 34 | binding.buttonClear.setVisible(setting.clearable) |
| 36 | !setting.setting.global || NativeConfig.isPerGameConfigLoaded() | ||
| 37 | ) | ||
| 38 | binding.buttonClear.setOnClickListener { | 35 | binding.buttonClear.setOnClickListener { |
| 39 | adapter.onClearClick(setting, bindingAdapterPosition) | 36 | adapter.onClearClick(setting, bindingAdapterPosition) |
| 40 | } | 37 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.kt index e2fe0b072..489f55455 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.kt | |||
| @@ -10,7 +10,6 @@ import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | |||
| 10 | import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting | 10 | import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting |
| 11 | import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting | 11 | import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting |
| 12 | import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter | 12 | import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter |
| 13 | import org.yuzu.yuzu_emu.utils.NativeConfig | ||
| 14 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible | 13 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible |
| 15 | 14 | ||
| 16 | class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : | 15 | class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : |
| @@ -48,9 +47,7 @@ class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Setti | |||
| 48 | binding.textSettingValue.setVisible(false) | 47 | binding.textSettingValue.setVisible(false) |
| 49 | } | 48 | } |
| 50 | 49 | ||
| 51 | binding.buttonClear.setVisible( | 50 | binding.buttonClear.setVisible(setting.clearable) |
| 52 | !setting.setting.global || NativeConfig.isPerGameConfigLoaded() | ||
| 53 | ) | ||
| 54 | binding.buttonClear.setOnClickListener { | 51 | binding.buttonClear.setOnClickListener { |
| 55 | adapter.onClearClick(setting, bindingAdapterPosition) | 52 | adapter.onClearClick(setting, bindingAdapterPosition) |
| 56 | } | 53 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SliderViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SliderViewHolder.kt index a37b59b44..90a7138cb 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SliderViewHolder.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SliderViewHolder.kt | |||
| @@ -9,7 +9,6 @@ import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding | |||
| 9 | import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | 9 | import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem |
| 10 | import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting | 10 | import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting |
| 11 | import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter | 11 | import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter |
| 12 | import org.yuzu.yuzu_emu.utils.NativeConfig | ||
| 13 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible | 12 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible |
| 14 | 13 | ||
| 15 | class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : | 14 | class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : |
| @@ -28,9 +27,7 @@ class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAda | |||
| 28 | setting.units | 27 | setting.units |
| 29 | ) | 28 | ) |
| 30 | 29 | ||
| 31 | binding.buttonClear.setVisible( | 30 | binding.buttonClear.setVisible(setting.clearable) |
| 32 | !setting.setting.global || NativeConfig.isPerGameConfigLoaded() | ||
| 33 | ) | ||
| 34 | binding.buttonClear.setOnClickListener { | 31 | binding.buttonClear.setOnClickListener { |
| 35 | adapter.onClearClick(setting, bindingAdapterPosition) | 32 | adapter.onClearClick(setting, bindingAdapterPosition) |
| 36 | } | 33 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/StringInputViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/StringInputViewHolder.kt new file mode 100644 index 000000000..a4fd36f62 --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/StringInputViewHolder.kt | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | package org.yuzu.yuzu_emu.features.settings.ui.viewholder | ||
| 5 | |||
| 6 | import android.view.View | ||
| 7 | import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding | ||
| 8 | import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | ||
| 9 | import org.yuzu.yuzu_emu.features.settings.model.view.StringInputSetting | ||
| 10 | import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter | ||
| 11 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible | ||
| 12 | |||
| 13 | class StringInputViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : | ||
| 14 | SettingViewHolder(binding.root, adapter) { | ||
| 15 | private lateinit var setting: StringInputSetting | ||
| 16 | |||
| 17 | override fun bind(item: SettingsItem) { | ||
| 18 | setting = item as StringInputSetting | ||
| 19 | binding.textSettingName.text = setting.title | ||
| 20 | binding.textSettingDescription.setVisible(setting.description.isNotEmpty()) | ||
| 21 | binding.textSettingDescription.text = setting.description | ||
| 22 | binding.textSettingValue.setVisible(true) | ||
| 23 | binding.textSettingValue.text = setting.getSelectedValue() | ||
| 24 | |||
| 25 | binding.buttonClear.setVisible(setting.clearable) | ||
| 26 | binding.buttonClear.setOnClickListener { | ||
| 27 | adapter.onClearClick(setting, bindingAdapterPosition) | ||
| 28 | } | ||
| 29 | |||
| 30 | setStyle(setting.isEditable, binding) | ||
| 31 | } | ||
| 32 | |||
| 33 | override fun onClick(clicked: View) { | ||
| 34 | if (setting.isEditable) { | ||
| 35 | adapter.onStringInputClick(setting, bindingAdapterPosition) | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | override fun onLongClick(clicked: View): Boolean { | ||
| 40 | if (setting.isEditable) { | ||
| 41 | return adapter.onLongClick(setting, bindingAdapterPosition) | ||
| 42 | } | ||
| 43 | return false | ||
| 44 | } | ||
| 45 | } | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt index 53f7b301f..e5763264a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt | |||
| @@ -9,7 +9,6 @@ import org.yuzu.yuzu_emu.databinding.ListItemSettingSwitchBinding | |||
| 9 | import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem | 9 | import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem |
| 10 | import org.yuzu.yuzu_emu.features.settings.model.view.SwitchSetting | 10 | import org.yuzu.yuzu_emu.features.settings.model.view.SwitchSetting |
| 11 | import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter | 11 | import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter |
| 12 | import org.yuzu.yuzu_emu.utils.NativeConfig | ||
| 13 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible | 12 | import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible |
| 14 | 13 | ||
| 15 | class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter: SettingsAdapter) : | 14 | class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter: SettingsAdapter) : |
| @@ -29,9 +28,7 @@ class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter | |||
| 29 | adapter.onBooleanClick(setting, binding.switchWidget.isChecked, bindingAdapterPosition) | 28 | adapter.onBooleanClick(setting, binding.switchWidget.isChecked, bindingAdapterPosition) |
| 30 | } | 29 | } |
| 31 | 30 | ||
| 32 | binding.buttonClear.setVisible( | 31 | binding.buttonClear.setVisible(setting.clearable) |
| 33 | !setting.setting.global || NativeConfig.isPerGameConfigLoaded() | ||
| 34 | ) | ||
| 35 | binding.buttonClear.setOnClickListener { | 32 | binding.buttonClear.setOnClickListener { |
| 36 | adapter.onClearClick(setting, bindingAdapterPosition) | 33 | adapter.onClearClick(setting, bindingAdapterPosition) |
| 37 | } | 34 | } |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt index c3b2b11f8..bcc880e17 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt | |||
| @@ -810,7 +810,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 810 | } | 810 | } |
| 811 | } | 811 | } |
| 812 | } | 812 | } |
| 813 | binding.doneControlConfig.setVisible(false) | 813 | binding.doneControlConfig.setVisible(true) |
| 814 | binding.surfaceInputOverlay.setIsInEditMode(true) | 814 | binding.surfaceInputOverlay.setIsInEditMode(true) |
| 815 | } | 815 | } |
| 816 | 816 | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt index 66907085a..737e03584 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt | |||
| @@ -28,6 +28,7 @@ import org.yuzu.yuzu_emu.features.input.NativeInput | |||
| 28 | import org.yuzu.yuzu_emu.R | 28 | import org.yuzu.yuzu_emu.R |
| 29 | import org.yuzu.yuzu_emu.features.input.model.NativeAnalog | 29 | import org.yuzu.yuzu_emu.features.input.model.NativeAnalog |
| 30 | import org.yuzu.yuzu_emu.features.input.model.NativeButton | 30 | import org.yuzu.yuzu_emu.features.input.model.NativeButton |
| 31 | import org.yuzu.yuzu_emu.features.input.model.NpadStyleIndex | ||
| 31 | import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting | 32 | import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting |
| 32 | import org.yuzu.yuzu_emu.features.settings.model.IntSetting | 33 | import org.yuzu.yuzu_emu.features.settings.model.IntSetting |
| 33 | import org.yuzu.yuzu_emu.overlay.model.OverlayControl | 34 | import org.yuzu.yuzu_emu.overlay.model.OverlayControl |
| @@ -99,12 +100,10 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : | |||
| 99 | } | 100 | } |
| 100 | 101 | ||
| 101 | var shouldUpdateView = false | 102 | var shouldUpdateView = false |
| 102 | val playerIndex = | 103 | val playerIndex = when (NativeInput.getStyleIndex(0)) { |
| 103 | if (NativeInput.isHandheldOnly()) { | 104 | NpadStyleIndex.Handheld -> 8 |
| 104 | NativeInput.ConsoleDevice | 105 | else -> 0 |
| 105 | } else { | 106 | } |
| 106 | NativeInput.Player1Device | ||
| 107 | } | ||
| 108 | 107 | ||
| 109 | for (button in overlayButtons) { | 108 | for (button in overlayButtons) { |
| 110 | if (!button.updateStatus(event)) { | 109 | if (!button.updateStatus(event)) { |
| @@ -664,7 +663,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : | |||
| 664 | 663 | ||
| 665 | val overlayControlData = NativeConfig.getOverlayControlData() | 664 | val overlayControlData = NativeConfig.getOverlayControlData() |
| 666 | overlayControlData.forEach { | 665 | overlayControlData.forEach { |
| 667 | it.enabled = OverlayControl.from(it.id)?.defaultVisibility == false | 666 | it.enabled = OverlayControl.from(it.id)?.defaultVisibility == true |
| 668 | } | 667 | } |
| 669 | NativeConfig.setOverlayControlData(overlayControlData) | 668 | NativeConfig.setOverlayControlData(overlayControlData) |
| 670 | 669 | ||
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 50cef5d2a..1226219ad 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp | |||
| @@ -292,6 +292,9 @@ void EmulationSession::ShutdownEmulation() { | |||
| 292 | // Unload user input. | 292 | // Unload user input. |
| 293 | m_system.HIDCore().UnloadInputDevices(); | 293 | m_system.HIDCore().UnloadInputDevices(); |
| 294 | 294 | ||
| 295 | // Enable all controllers | ||
| 296 | m_system.HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All}); | ||
| 297 | |||
| 295 | // Shutdown the main emulated process | 298 | // Shutdown the main emulated process |
| 296 | if (m_load_result == Core::SystemResultStatus::Success) { | 299 | if (m_load_result == Core::SystemResultStatus::Success) { |
| 297 | m_system.DetachDebugger(); | 300 | m_system.DetachDebugger(); |
| @@ -404,7 +407,9 @@ static Core::SystemResultStatus RunEmulation(const std::string& filepath, | |||
| 404 | const size_t program_index, | 407 | const size_t program_index, |
| 405 | const bool frontend_initiated) { | 408 | const bool frontend_initiated) { |
| 406 | MicroProfileOnThreadCreate("EmuThread"); | 409 | MicroProfileOnThreadCreate("EmuThread"); |
| 407 | SCOPE_EXIT({ MicroProfileShutdown(); }); | 410 | SCOPE_EXIT { |
| 411 | MicroProfileShutdown(); | ||
| 412 | }; | ||
| 408 | 413 | ||
| 409 | LOG_INFO(Frontend, "starting"); | 414 | LOG_INFO(Frontend, "starting"); |
| 410 | 415 | ||
| @@ -413,7 +418,9 @@ static Core::SystemResultStatus RunEmulation(const std::string& filepath, | |||
| 413 | return Core::SystemResultStatus::ErrorLoader; | 418 | return Core::SystemResultStatus::ErrorLoader; |
| 414 | } | 419 | } |
| 415 | 420 | ||
| 416 | SCOPE_EXIT({ EmulationSession::GetInstance().ShutdownEmulation(); }); | 421 | SCOPE_EXIT { |
| 422 | EmulationSession::GetInstance().ShutdownEmulation(); | ||
| 423 | }; | ||
| 417 | 424 | ||
| 418 | jconst result = EmulationSession::GetInstance().InitializeEmulation(filepath, program_index, | 425 | jconst result = EmulationSession::GetInstance().InitializeEmulation(filepath, program_index, |
| 419 | frontend_initiated); | 426 | frontend_initiated); |
diff --git a/src/android/app/src/main/jni/native_input.cpp b/src/android/app/src/main/jni/native_input.cpp index 37a65f2b8..4935a4607 100644 --- a/src/android/app/src/main/jni/native_input.cpp +++ b/src/android/app/src/main/jni/native_input.cpp | |||
| @@ -102,8 +102,50 @@ void ApplyControllerConfig(size_t player_index, | |||
| 102 | } | 102 | } |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | std::vector<s32> GetSupportedStyles(int player_index) { | ||
| 106 | auto& hid_core = EmulationSession::GetInstance().System().HIDCore(); | ||
| 107 | const auto npad_style_set = hid_core.GetSupportedStyleTag(); | ||
| 108 | std::vector<s32> supported_indexes; | ||
| 109 | if (npad_style_set.fullkey == 1) { | ||
| 110 | supported_indexes.push_back(static_cast<s32>(Core::HID::NpadStyleIndex::Fullkey)); | ||
| 111 | } | ||
| 112 | |||
| 113 | if (npad_style_set.joycon_dual == 1) { | ||
| 114 | supported_indexes.push_back(static_cast<s32>(Core::HID::NpadStyleIndex::JoyconDual)); | ||
| 115 | } | ||
| 116 | |||
| 117 | if (npad_style_set.joycon_left == 1) { | ||
| 118 | supported_indexes.push_back(static_cast<s32>(Core::HID::NpadStyleIndex::JoyconLeft)); | ||
| 119 | } | ||
| 120 | |||
| 121 | if (npad_style_set.joycon_right == 1) { | ||
| 122 | supported_indexes.push_back(static_cast<s32>(Core::HID::NpadStyleIndex::JoyconRight)); | ||
| 123 | } | ||
| 124 | |||
| 125 | if (player_index == 0 && npad_style_set.handheld == 1) { | ||
| 126 | supported_indexes.push_back(static_cast<s32>(Core::HID::NpadStyleIndex::Handheld)); | ||
| 127 | } | ||
| 128 | |||
| 129 | if (npad_style_set.gamecube == 1) { | ||
| 130 | supported_indexes.push_back(static_cast<s32>(Core::HID::NpadStyleIndex::GameCube)); | ||
| 131 | } | ||
| 132 | |||
| 133 | return supported_indexes; | ||
| 134 | } | ||
| 135 | |||
| 105 | void ConnectController(size_t player_index, bool connected) { | 136 | void ConnectController(size_t player_index, bool connected) { |
| 106 | auto& hid_core = EmulationSession::GetInstance().System().HIDCore(); | 137 | auto& hid_core = EmulationSession::GetInstance().System().HIDCore(); |
| 138 | ApplyControllerConfig(player_index, [&](Core::HID::EmulatedController* controller) { | ||
| 139 | auto supported_styles = GetSupportedStyles(player_index); | ||
| 140 | auto controller_style = controller->GetNpadStyleIndex(true); | ||
| 141 | auto style = std::find(supported_styles.begin(), supported_styles.end(), | ||
| 142 | static_cast<int>(controller_style)); | ||
| 143 | if (style == supported_styles.end() && !supported_styles.empty()) { | ||
| 144 | controller->SetNpadStyleIndex( | ||
| 145 | static_cast<Core::HID::NpadStyleIndex>(supported_styles[0])); | ||
| 146 | } | ||
| 147 | }); | ||
| 148 | |||
| 107 | if (player_index == 0) { | 149 | if (player_index == 0) { |
| 108 | auto* handheld = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); | 150 | auto* handheld = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); |
| 109 | auto* player_one = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); | 151 | auto* player_one = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); |
| @@ -522,36 +564,10 @@ jint Java_org_yuzu_yuzu_1emu_features_input_NativeInput_getButtonNameImpl(JNIEnv | |||
| 522 | 564 | ||
| 523 | jintArray Java_org_yuzu_yuzu_1emu_features_input_NativeInput_getSupportedStyleTagsImpl( | 565 | jintArray Java_org_yuzu_yuzu_1emu_features_input_NativeInput_getSupportedStyleTagsImpl( |
| 524 | JNIEnv* env, jobject j_obj, jint j_player_index) { | 566 | JNIEnv* env, jobject j_obj, jint j_player_index) { |
| 525 | auto& hid_core = EmulationSession::GetInstance().System().HIDCore(); | 567 | auto supported_styles = GetSupportedStyles(j_player_index); |
| 526 | const auto npad_style_set = hid_core.GetSupportedStyleTag(); | 568 | jintArray j_supported_indexes = env->NewIntArray(supported_styles.size()); |
| 527 | std::vector<s32> supported_indexes; | 569 | env->SetIntArrayRegion(j_supported_indexes, 0, supported_styles.size(), |
| 528 | if (npad_style_set.fullkey == 1) { | 570 | supported_styles.data()); |
| 529 | supported_indexes.push_back(static_cast<u32>(Core::HID::NpadStyleIndex::Fullkey)); | ||
| 530 | } | ||
| 531 | |||
| 532 | if (npad_style_set.joycon_dual == 1) { | ||
| 533 | supported_indexes.push_back(static_cast<u32>(Core::HID::NpadStyleIndex::JoyconDual)); | ||
| 534 | } | ||
| 535 | |||
| 536 | if (npad_style_set.joycon_left == 1) { | ||
| 537 | supported_indexes.push_back(static_cast<u32>(Core::HID::NpadStyleIndex::JoyconLeft)); | ||
| 538 | } | ||
| 539 | |||
| 540 | if (npad_style_set.joycon_right == 1) { | ||
| 541 | supported_indexes.push_back(static_cast<u32>(Core::HID::NpadStyleIndex::JoyconRight)); | ||
| 542 | } | ||
| 543 | |||
| 544 | if (j_player_index == 0 && npad_style_set.handheld == 1) { | ||
| 545 | supported_indexes.push_back(static_cast<u32>(Core::HID::NpadStyleIndex::Handheld)); | ||
| 546 | } | ||
| 547 | |||
| 548 | if (npad_style_set.gamecube == 1) { | ||
| 549 | supported_indexes.push_back(static_cast<u32>(Core::HID::NpadStyleIndex::GameCube)); | ||
| 550 | } | ||
| 551 | |||
| 552 | jintArray j_supported_indexes = env->NewIntArray(supported_indexes.size()); | ||
| 553 | env->SetIntArrayRegion(j_supported_indexes, 0, supported_indexes.size(), | ||
| 554 | supported_indexes.data()); | ||
| 555 | return j_supported_indexes; | 571 | return j_supported_indexes; |
| 556 | } | 572 | } |
| 557 | 573 | ||
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 6a631f664..f7f19cdad 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml | |||
| @@ -209,6 +209,7 @@ | |||
| 209 | <string name="value_with_units">%1$s%2$s</string> | 209 | <string name="value_with_units">%1$s%2$s</string> |
| 210 | 210 | ||
| 211 | <!-- System settings strings --> | 211 | <!-- System settings strings --> |
| 212 | <string name="device_name">Device name</string> | ||
| 212 | <string name="use_docked_mode">Docked Mode</string> | 213 | <string name="use_docked_mode">Docked Mode</string> |
| 213 | <string name="use_docked_mode_description">Increases resolution, decreasing performance. Handheld Mode is used when disabled, lowering resolution and increasing performance.</string> | 214 | <string name="use_docked_mode_description">Increases resolution, decreasing performance. Handheld Mode is used when disabled, lowering resolution and increasing performance.</string> |
| 214 | <string name="emulated_region">Emulated region</string> | 215 | <string name="emulated_region">Emulated region</string> |
diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp index d97ca2a40..49efae8e3 100644 --- a/src/audio_core/sink/cubeb_sink.cpp +++ b/src/audio_core/sink/cubeb_sink.cpp | |||
| @@ -357,7 +357,9 @@ bool IsCubebSuitable() { | |||
| 357 | return false; | 357 | return false; |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | SCOPE_EXIT({ cubeb_destroy(ctx); }); | 360 | SCOPE_EXIT { |
| 361 | cubeb_destroy(ctx); | ||
| 362 | }; | ||
| 361 | 363 | ||
| 362 | #ifdef _WIN32 | 364 | #ifdef _WIN32 |
| 363 | if (SUCCEEDED(com_init_result)) { | 365 | if (SUCCEEDED(com_init_result)) { |
diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp index c047b0668..0a98eb31e 100644 --- a/src/audio_core/sink/sink_stream.cpp +++ b/src/audio_core/sink/sink_stream.cpp | |||
| @@ -20,10 +20,10 @@ | |||
| 20 | namespace AudioCore::Sink { | 20 | namespace AudioCore::Sink { |
| 21 | 21 | ||
| 22 | void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) { | 22 | void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) { |
| 23 | SCOPE_EXIT({ | 23 | SCOPE_EXIT { |
| 24 | queue.enqueue(buffer); | 24 | queue.enqueue(buffer); |
| 25 | ++queued_buffers; | 25 | ++queued_buffers; |
| 26 | }); | 26 | }; |
| 27 | 27 | ||
| 28 | if (type == StreamType::In) { | 28 | if (type == StreamType::In) { |
| 29 | return; | 29 | return; |
diff --git a/src/common/demangle.cpp b/src/common/demangle.cpp index 6e117cb41..b2c9d126a 100644 --- a/src/common/demangle.cpp +++ b/src/common/demangle.cpp | |||
| @@ -20,7 +20,9 @@ std::string DemangleSymbol(const std::string& mangled) { | |||
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | char* demangled = nullptr; | 22 | char* demangled = nullptr; |
| 23 | SCOPE_EXIT({ std::free(demangled); }); | 23 | SCOPE_EXIT { |
| 24 | std::free(demangled); | ||
| 25 | }; | ||
| 24 | 26 | ||
| 25 | if (is_itanium(mangled)) { | 27 | if (is_itanium(mangled)) { |
| 26 | demangled = llvm::itaniumDemangle(mangled.c_str()); | 28 | demangled = llvm::itaniumDemangle(mangled.c_str()); |
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 860c39e6a..e0b5a6a67 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp | |||
| @@ -430,11 +430,11 @@ public: | |||
| 430 | explicit Impl(size_t backing_size_, size_t virtual_size_) | 430 | explicit Impl(size_t backing_size_, size_t virtual_size_) |
| 431 | : backing_size{backing_size_}, virtual_size{virtual_size_} { | 431 | : backing_size{backing_size_}, virtual_size{virtual_size_} { |
| 432 | bool good = false; | 432 | bool good = false; |
| 433 | SCOPE_EXIT({ | 433 | SCOPE_EXIT { |
| 434 | if (!good) { | 434 | if (!good) { |
| 435 | Release(); | 435 | Release(); |
| 436 | } | 436 | } |
| 437 | }); | 437 | }; |
| 438 | 438 | ||
| 439 | long page_size = sysconf(_SC_PAGESIZE); | 439 | long page_size = sysconf(_SC_PAGESIZE); |
| 440 | if (page_size != 0x1000) { | 440 | if (page_size != 0x1000) { |
diff --git a/src/common/page_table.cpp b/src/common/page_table.cpp index 85dc18c11..3205eb7da 100644 --- a/src/common/page_table.cpp +++ b/src/common/page_table.cpp | |||
| @@ -24,10 +24,10 @@ bool PageTable::ContinueTraversal(TraversalEntry* out_entry, TraversalContext* c | |||
| 24 | out_entry->block_size = page_size; | 24 | out_entry->block_size = page_size; |
| 25 | 25 | ||
| 26 | // Regardless of whether the page was mapped, advance on exit. | 26 | // Regardless of whether the page was mapped, advance on exit. |
| 27 | SCOPE_EXIT({ | 27 | SCOPE_EXIT { |
| 28 | context->next_page += 1; | 28 | context->next_page += 1; |
| 29 | context->next_offset += page_size; | 29 | context->next_offset += page_size; |
| 30 | }); | 30 | }; |
| 31 | 31 | ||
| 32 | // Validate that we can read the actual entry. | 32 | // Validate that we can read the actual entry. |
| 33 | const auto page = context->next_page; | 33 | const auto page = context->next_page; |
diff --git a/src/common/scope_exit.h b/src/common/scope_exit.h index e9c789c88..f3e88cde9 100644 --- a/src/common/scope_exit.h +++ b/src/common/scope_exit.h | |||
| @@ -7,29 +7,61 @@ | |||
| 7 | #include "common/common_funcs.h" | 7 | #include "common/common_funcs.h" |
| 8 | 8 | ||
| 9 | namespace detail { | 9 | namespace detail { |
| 10 | template <typename Func> | 10 | template <class F> |
| 11 | struct ScopeExitHelper { | 11 | class ScopeGuard { |
| 12 | explicit ScopeExitHelper(Func&& func_) : func(std::move(func_)) {} | 12 | YUZU_NON_COPYABLE(ScopeGuard); |
| 13 | ~ScopeExitHelper() { | 13 | |
| 14 | private: | ||
| 15 | F f; | ||
| 16 | bool active; | ||
| 17 | |||
| 18 | public: | ||
| 19 | constexpr ScopeGuard(F f_) : f(std::move(f_)), active(true) {} | ||
| 20 | constexpr ~ScopeGuard() { | ||
| 14 | if (active) { | 21 | if (active) { |
| 15 | func(); | 22 | f(); |
| 16 | } | 23 | } |
| 17 | } | 24 | } |
| 18 | 25 | constexpr void Cancel() { | |
| 19 | void Cancel() { | ||
| 20 | active = false; | 26 | active = false; |
| 21 | } | 27 | } |
| 22 | 28 | ||
| 23 | Func func; | 29 | constexpr ScopeGuard(ScopeGuard&& rhs) : f(std::move(rhs.f)), active(rhs.active) { |
| 24 | bool active{true}; | 30 | rhs.Cancel(); |
| 31 | } | ||
| 32 | |||
| 33 | ScopeGuard& operator=(ScopeGuard&& rhs) = delete; | ||
| 25 | }; | 34 | }; |
| 26 | 35 | ||
| 27 | template <typename Func> | 36 | template <class F> |
| 28 | ScopeExitHelper<Func> ScopeExit(Func&& func) { | 37 | constexpr ScopeGuard<F> MakeScopeGuard(F f) { |
| 29 | return ScopeExitHelper<Func>(std::forward<Func>(func)); | 38 | return ScopeGuard<F>(std::move(f)); |
| 30 | } | 39 | } |
| 40 | |||
| 41 | enum class ScopeGuardOnExit {}; | ||
| 42 | |||
| 43 | template <typename F> | ||
| 44 | constexpr ScopeGuard<F> operator+(ScopeGuardOnExit, F&& f) { | ||
| 45 | return ScopeGuard<F>(std::forward<F>(f)); | ||
| 46 | } | ||
| 47 | |||
| 31 | } // namespace detail | 48 | } // namespace detail |
| 32 | 49 | ||
| 50 | #define CONCATENATE_IMPL(s1, s2) s1##s2 | ||
| 51 | #define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2) | ||
| 52 | |||
| 53 | #ifdef __COUNTER__ | ||
| 54 | #define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __COUNTER__) | ||
| 55 | #else | ||
| 56 | #define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __LINE__) | ||
| 57 | #endif | ||
| 58 | |||
| 59 | /** | ||
| 60 | * This macro is similar to SCOPE_EXIT, except the object is caller managed. This is intended to be | ||
| 61 | * used when the caller might want to cancel the ScopeExit. | ||
| 62 | */ | ||
| 63 | #define SCOPE_GUARD detail::ScopeGuardOnExit() + [&]() | ||
| 64 | |||
| 33 | /** | 65 | /** |
| 34 | * This macro allows you to conveniently specify a block of code that will run on scope exit. Handy | 66 | * This macro allows you to conveniently specify a block of code that will run on scope exit. Handy |
| 35 | * for doing ad-hoc clean-up tasks in a function with multiple returns. | 67 | * for doing ad-hoc clean-up tasks in a function with multiple returns. |
| @@ -38,7 +70,7 @@ ScopeExitHelper<Func> ScopeExit(Func&& func) { | |||
| 38 | * \code | 70 | * \code |
| 39 | * const int saved_val = g_foo; | 71 | * const int saved_val = g_foo; |
| 40 | * g_foo = 55; | 72 | * g_foo = 55; |
| 41 | * SCOPE_EXIT({ g_foo = saved_val; }); | 73 | * SCOPE_EXIT{ g_foo = saved_val; }; |
| 42 | * | 74 | * |
| 43 | * if (Bar()) { | 75 | * if (Bar()) { |
| 44 | * return 0; | 76 | * return 0; |
| @@ -47,10 +79,4 @@ ScopeExitHelper<Func> ScopeExit(Func&& func) { | |||
| 47 | * } | 79 | * } |
| 48 | * \endcode | 80 | * \endcode |
| 49 | */ | 81 | */ |
| 50 | #define SCOPE_EXIT(body) auto CONCAT2(scope_exit_helper_, __LINE__) = detail::ScopeExit([&]() body) | 82 | #define SCOPE_EXIT auto ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE_) = SCOPE_GUARD |
| 51 | |||
| 52 | /** | ||
| 53 | * This macro is similar to SCOPE_EXIT, except the object is caller managed. This is intended to be | ||
| 54 | * used when the caller might want to cancel the ScopeExit. | ||
| 55 | */ | ||
| 56 | #define SCOPE_GUARD(body) detail::ScopeExit([&]() body) | ||
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 7770dbeae..f67a12f8f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -2,8 +2,8 @@ | |||
| 2 | # SPDX-License-Identifier: GPL-2.0-or-later | 2 | # SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | add_library(core STATIC | 4 | add_library(core STATIC |
| 5 | arm/arm_interface.h | ||
| 6 | arm/arm_interface.cpp | 5 | arm/arm_interface.cpp |
| 6 | arm/arm_interface.h | ||
| 7 | arm/debug.cpp | 7 | arm/debug.cpp |
| 8 | arm/debug.h | 8 | arm/debug.h |
| 9 | arm/exclusive_monitor.cpp | 9 | arm/exclusive_monitor.cpp |
| @@ -37,10 +37,10 @@ add_library(core STATIC | |||
| 37 | debugger/gdbstub.h | 37 | debugger/gdbstub.h |
| 38 | debugger/gdbstub_arch.cpp | 38 | debugger/gdbstub_arch.cpp |
| 39 | debugger/gdbstub_arch.h | 39 | debugger/gdbstub_arch.h |
| 40 | device_memory_manager.h | ||
| 41 | device_memory_manager.inc | ||
| 42 | device_memory.cpp | 40 | device_memory.cpp |
| 43 | device_memory.h | 41 | device_memory.h |
| 42 | device_memory_manager.h | ||
| 43 | device_memory_manager.inc | ||
| 44 | file_sys/bis_factory.cpp | 44 | file_sys/bis_factory.cpp |
| 45 | file_sys/bis_factory.h | 45 | file_sys/bis_factory.h |
| 46 | file_sys/card_image.cpp | 46 | file_sys/card_image.cpp |
| @@ -390,6 +390,20 @@ add_library(core STATIC | |||
| 390 | hle/service/acc/errors.h | 390 | hle/service/acc/errors.h |
| 391 | hle/service/acc/profile_manager.cpp | 391 | hle/service/acc/profile_manager.cpp |
| 392 | hle/service/acc/profile_manager.h | 392 | hle/service/acc/profile_manager.h |
| 393 | hle/service/am/am.cpp | ||
| 394 | hle/service/am/am.h | ||
| 395 | hle/service/am/am_results.h | ||
| 396 | hle/service/am/am_types.h | ||
| 397 | hle/service/am/applet.cpp | ||
| 398 | hle/service/am/applet.h | ||
| 399 | hle/service/am/applet_data_broker.cpp | ||
| 400 | hle/service/am/applet_data_broker.h | ||
| 401 | hle/service/am/applet_manager.cpp | ||
| 402 | hle/service/am/applet_manager.h | ||
| 403 | hle/service/am/applet_message_queue.cpp | ||
| 404 | hle/service/am/applet_message_queue.h | ||
| 405 | hle/service/am/display_layer_manager.cpp | ||
| 406 | hle/service/am/display_layer_manager.h | ||
| 393 | hle/service/am/frontend/applet_cabinet.cpp | 407 | hle/service/am/frontend/applet_cabinet.cpp |
| 394 | hle/service/am/frontend/applet_cabinet.h | 408 | hle/service/am/frontend/applet_cabinet.h |
| 395 | hle/service/am/frontend/applet_controller.cpp | 409 | hle/service/am/frontend/applet_controller.cpp |
| @@ -411,24 +425,10 @@ add_library(core STATIC | |||
| 411 | hle/service/am/frontend/applet_web_browser_types.h | 425 | hle/service/am/frontend/applet_web_browser_types.h |
| 412 | hle/service/am/frontend/applets.cpp | 426 | hle/service/am/frontend/applets.cpp |
| 413 | hle/service/am/frontend/applets.h | 427 | hle/service/am/frontend/applets.h |
| 414 | hle/service/am/am.cpp | ||
| 415 | hle/service/am/am.h | ||
| 416 | hle/service/am/am_results.h | ||
| 417 | hle/service/am/am_types.h | ||
| 418 | hle/service/am/applet.cpp | ||
| 419 | hle/service/am/applet.h | ||
| 420 | hle/service/am/applet_manager.cpp | ||
| 421 | hle/service/am/applet_data_broker.cpp | ||
| 422 | hle/service/am/applet_data_broker.h | ||
| 423 | hle/service/am/applet_manager.h | ||
| 424 | hle/service/am/applet_message_queue.cpp | ||
| 425 | hle/service/am/applet_message_queue.h | ||
| 426 | hle/service/am/hid_registration.cpp | 428 | hle/service/am/hid_registration.cpp |
| 427 | hle/service/am/hid_registration.h | 429 | hle/service/am/hid_registration.h |
| 428 | hle/service/am/library_applet_storage.cpp | 430 | hle/service/am/library_applet_storage.cpp |
| 429 | hle/service/am/library_applet_storage.h | 431 | hle/service/am/library_applet_storage.h |
| 430 | hle/service/am/managed_layer_holder.cpp | ||
| 431 | hle/service/am/managed_layer_holder.h | ||
| 432 | hle/service/am/process.cpp | 432 | hle/service/am/process.cpp |
| 433 | hle/service/am/process.h | 433 | hle/service/am/process.h |
| 434 | hle/service/am/service/all_system_applet_proxies_service.cpp | 434 | hle/service/am/service/all_system_applet_proxies_service.cpp |
| @@ -441,10 +441,10 @@ add_library(core STATIC | |||
| 441 | hle/service/am/service/application_creator.h | 441 | hle/service/am/service/application_creator.h |
| 442 | hle/service/am/service/application_functions.cpp | 442 | hle/service/am/service/application_functions.cpp |
| 443 | hle/service/am/service/application_functions.h | 443 | hle/service/am/service/application_functions.h |
| 444 | hle/service/am/service/application_proxy_service.cpp | ||
| 445 | hle/service/am/service/application_proxy_service.h | ||
| 446 | hle/service/am/service/application_proxy.cpp | 444 | hle/service/am/service/application_proxy.cpp |
| 447 | hle/service/am/service/application_proxy.h | 445 | hle/service/am/service/application_proxy.h |
| 446 | hle/service/am/service/application_proxy_service.cpp | ||
| 447 | hle/service/am/service/application_proxy_service.h | ||
| 448 | hle/service/am/service/audio_controller.cpp | 448 | hle/service/am/service/audio_controller.cpp |
| 449 | hle/service/am/service/audio_controller.h | 449 | hle/service/am/service/audio_controller.h |
| 450 | hle/service/am/service/common_state_getter.cpp | 450 | hle/service/am/service/common_state_getter.cpp |
| @@ -473,16 +473,14 @@ add_library(core STATIC | |||
| 473 | hle/service/am/service/process_winding_controller.h | 473 | hle/service/am/service/process_winding_controller.h |
| 474 | hle/service/am/service/self_controller.cpp | 474 | hle/service/am/service/self_controller.cpp |
| 475 | hle/service/am/service/self_controller.h | 475 | hle/service/am/service/self_controller.h |
| 476 | hle/service/am/service/storage_accessor.cpp | ||
| 477 | hle/service/am/service/storage_accessor.h | ||
| 478 | hle/service/am/service/storage.cpp | 476 | hle/service/am/service/storage.cpp |
| 479 | hle/service/am/service/storage.h | 477 | hle/service/am/service/storage.h |
| 478 | hle/service/am/service/storage_accessor.cpp | ||
| 479 | hle/service/am/service/storage_accessor.h | ||
| 480 | hle/service/am/service/system_applet_proxy.cpp | 480 | hle/service/am/service/system_applet_proxy.cpp |
| 481 | hle/service/am/service/system_applet_proxy.h | 481 | hle/service/am/service/system_applet_proxy.h |
| 482 | hle/service/am/service/window_controller.cpp | 482 | hle/service/am/service/window_controller.cpp |
| 483 | hle/service/am/service/window_controller.h | 483 | hle/service/am/service/window_controller.h |
| 484 | hle/service/am/system_buffer_manager.cpp | ||
| 485 | hle/service/am/system_buffer_manager.h | ||
| 486 | hle/service/aoc/aoc_u.cpp | 484 | hle/service/aoc/aoc_u.cpp |
| 487 | hle/service/aoc/aoc_u.h | 485 | hle/service/aoc/aoc_u.h |
| 488 | hle/service/apm/apm.cpp | 486 | hle/service/apm/apm.cpp |
| @@ -491,12 +489,12 @@ add_library(core STATIC | |||
| 491 | hle/service/apm/apm_controller.h | 489 | hle/service/apm/apm_controller.h |
| 492 | hle/service/apm/apm_interface.cpp | 490 | hle/service/apm/apm_interface.cpp |
| 493 | hle/service/apm/apm_interface.h | 491 | hle/service/apm/apm_interface.h |
| 494 | hle/service/audio/audctl.cpp | ||
| 495 | hle/service/audio/audctl.h | ||
| 496 | hle/service/audio/audin_u.cpp | 492 | hle/service/audio/audin_u.cpp |
| 497 | hle/service/audio/audin_u.h | 493 | hle/service/audio/audin_u.h |
| 498 | hle/service/audio/audio.cpp | 494 | hle/service/audio/audio.cpp |
| 499 | hle/service/audio/audio.h | 495 | hle/service/audio/audio.h |
| 496 | hle/service/audio/audio_controller.cpp | ||
| 497 | hle/service/audio/audio_controller.h | ||
| 500 | hle/service/audio/audout_u.cpp | 498 | hle/service/audio/audout_u.cpp |
| 501 | hle/service/audio/audout_u.h | 499 | hle/service/audio/audout_u.h |
| 502 | hle/service/audio/audrec_a.cpp | 500 | hle/service/audio/audrec_a.cpp |
| @@ -510,18 +508,6 @@ add_library(core STATIC | |||
| 510 | hle/service/audio/hwopus.h | 508 | hle/service/audio/hwopus.h |
| 511 | hle/service/bcat/backend/backend.cpp | 509 | hle/service/bcat/backend/backend.cpp |
| 512 | hle/service/bcat/backend/backend.h | 510 | hle/service/bcat/backend/backend.h |
| 513 | hle/service/bcat/news/newly_arrived_event_holder.cpp | ||
| 514 | hle/service/bcat/news/newly_arrived_event_holder.h | ||
| 515 | hle/service/bcat/news/news_data_service.cpp | ||
| 516 | hle/service/bcat/news/news_data_service.h | ||
| 517 | hle/service/bcat/news/news_database_service.cpp | ||
| 518 | hle/service/bcat/news/news_database_service.h | ||
| 519 | hle/service/bcat/news/news_service.cpp | ||
| 520 | hle/service/bcat/news/news_service.h | ||
| 521 | hle/service/bcat/news/overwrite_event_holder.cpp | ||
| 522 | hle/service/bcat/news/overwrite_event_holder.h | ||
| 523 | hle/service/bcat/news/service_creator.cpp | ||
| 524 | hle/service/bcat/news/service_creator.h | ||
| 525 | hle/service/bcat/bcat.cpp | 511 | hle/service/bcat/bcat.cpp |
| 526 | hle/service/bcat/bcat.h | 512 | hle/service/bcat/bcat.h |
| 527 | hle/service/bcat/bcat_result.h | 513 | hle/service/bcat/bcat_result.h |
| @@ -537,6 +523,18 @@ add_library(core STATIC | |||
| 537 | hle/service/bcat/delivery_cache_progress_service.h | 523 | hle/service/bcat/delivery_cache_progress_service.h |
| 538 | hle/service/bcat/delivery_cache_storage_service.cpp | 524 | hle/service/bcat/delivery_cache_storage_service.cpp |
| 539 | hle/service/bcat/delivery_cache_storage_service.h | 525 | hle/service/bcat/delivery_cache_storage_service.h |
| 526 | hle/service/bcat/news/newly_arrived_event_holder.cpp | ||
| 527 | hle/service/bcat/news/newly_arrived_event_holder.h | ||
| 528 | hle/service/bcat/news/news_data_service.cpp | ||
| 529 | hle/service/bcat/news/news_data_service.h | ||
| 530 | hle/service/bcat/news/news_database_service.cpp | ||
| 531 | hle/service/bcat/news/news_database_service.h | ||
| 532 | hle/service/bcat/news/news_service.cpp | ||
| 533 | hle/service/bcat/news/news_service.h | ||
| 534 | hle/service/bcat/news/overwrite_event_holder.cpp | ||
| 535 | hle/service/bcat/news/overwrite_event_holder.h | ||
| 536 | hle/service/bcat/news/service_creator.cpp | ||
| 537 | hle/service/bcat/news/service_creator.h | ||
| 540 | hle/service/bcat/service_creator.cpp | 538 | hle/service/bcat/service_creator.cpp |
| 541 | hle/service/bcat/service_creator.h | 539 | hle/service/bcat/service_creator.h |
| 542 | hle/service/bpc/bpc.cpp | 540 | hle/service/bpc/bpc.cpp |
| @@ -545,6 +543,16 @@ add_library(core STATIC | |||
| 545 | hle/service/btdrv/btdrv.h | 543 | hle/service/btdrv/btdrv.h |
| 546 | hle/service/btm/btm.cpp | 544 | hle/service/btm/btm.cpp |
| 547 | hle/service/btm/btm.h | 545 | hle/service/btm/btm.h |
| 546 | hle/service/btm/btm_debug.cpp | ||
| 547 | hle/service/btm/btm_debug.h | ||
| 548 | hle/service/btm/btm_system.cpp | ||
| 549 | hle/service/btm/btm_system.h | ||
| 550 | hle/service/btm/btm_system_core.cpp | ||
| 551 | hle/service/btm/btm_system_core.h | ||
| 552 | hle/service/btm/btm_user.cpp | ||
| 553 | hle/service/btm/btm_user.h | ||
| 554 | hle/service/btm/btm_user_core.cpp | ||
| 555 | hle/service/btm/btm_user_core.h | ||
| 548 | hle/service/caps/caps.cpp | 556 | hle/service/caps/caps.cpp |
| 549 | hle/service/caps/caps.h | 557 | hle/service/caps/caps.h |
| 550 | hle/service/caps/caps_a.cpp | 558 | hle/service/caps/caps_a.cpp |
| @@ -600,8 +608,6 @@ add_library(core STATIC | |||
| 600 | hle/service/filesystem/romfs_controller.h | 608 | hle/service/filesystem/romfs_controller.h |
| 601 | hle/service/filesystem/save_data_controller.cpp | 609 | hle/service/filesystem/save_data_controller.cpp |
| 602 | hle/service/filesystem/save_data_controller.h | 610 | hle/service/filesystem/save_data_controller.h |
| 603 | hle/service/fgm/fgm.cpp | ||
| 604 | hle/service/fgm/fgm.h | ||
| 605 | hle/service/friend/friend.cpp | 611 | hle/service/friend/friend.cpp |
| 606 | hle/service/friend/friend.h | 612 | hle/service/friend/friend.h |
| 607 | hle/service/friend/friend_interface.cpp | 613 | hle/service/friend/friend_interface.cpp |
| @@ -739,15 +745,48 @@ add_library(core STATIC | |||
| 739 | hle/service/nim/nim.h | 745 | hle/service/nim/nim.h |
| 740 | hle/service/npns/npns.cpp | 746 | hle/service/npns/npns.cpp |
| 741 | hle/service/npns/npns.h | 747 | hle/service/npns/npns.h |
| 742 | hle/service/ns/errors.h | 748 | hle/service/ns/account_proxy_interface.cpp |
| 743 | hle/service/ns/iplatform_service_manager.cpp | 749 | hle/service/ns/account_proxy_interface.h |
| 744 | hle/service/ns/iplatform_service_manager.h | 750 | hle/service/ns/application_manager_interface.cpp |
| 751 | hle/service/ns/application_manager_interface.h | ||
| 752 | hle/service/ns/application_version_interface.cpp | ||
| 753 | hle/service/ns/application_version_interface.h | ||
| 754 | hle/service/ns/content_management_interface.cpp | ||
| 755 | hle/service/ns/content_management_interface.h | ||
| 756 | hle/service/ns/develop_interface.cpp | ||
| 757 | hle/service/ns/develop_interface.h | ||
| 758 | hle/service/ns/document_interface.cpp | ||
| 759 | hle/service/ns/document_interface.h | ||
| 760 | hle/service/ns/download_task_interface.cpp | ||
| 761 | hle/service/ns/download_task_interface.h | ||
| 762 | hle/service/ns/dynamic_rights_interface.cpp | ||
| 763 | hle/service/ns/dynamic_rights_interface.h | ||
| 764 | hle/service/ns/ecommerce_interface.cpp | ||
| 765 | hle/service/ns/ecommerce_interface.h | ||
| 766 | hle/service/ns/factory_reset_interface.cpp | ||
| 767 | hle/service/ns/factory_reset_interface.h | ||
| 745 | hle/service/ns/language.cpp | 768 | hle/service/ns/language.cpp |
| 746 | hle/service/ns/language.h | 769 | hle/service/ns/language.h |
| 747 | hle/service/ns/ns.cpp | 770 | hle/service/ns/ns.cpp |
| 748 | hle/service/ns/ns.h | 771 | hle/service/ns/ns.h |
| 749 | hle/service/ns/pdm_qry.cpp | 772 | hle/service/ns/ns_results.h |
| 750 | hle/service/ns/pdm_qry.h | 773 | hle/service/ns/ns_types.h |
| 774 | hle/service/ns/platform_service_manager.cpp | ||
| 775 | hle/service/ns/platform_service_manager.h | ||
| 776 | hle/service/ns/query_service.cpp | ||
| 777 | hle/service/ns/query_service.h | ||
| 778 | hle/service/ns/read_only_application_control_data_interface.cpp | ||
| 779 | hle/service/ns/read_only_application_control_data_interface.h | ||
| 780 | hle/service/ns/read_only_application_record_interface.cpp | ||
| 781 | hle/service/ns/read_only_application_record_interface.h | ||
| 782 | hle/service/ns/service_getter_interface.cpp | ||
| 783 | hle/service/ns/service_getter_interface.h | ||
| 784 | hle/service/ns/system_update_control.cpp | ||
| 785 | hle/service/ns/system_update_control.h | ||
| 786 | hle/service/ns/system_update_interface.cpp | ||
| 787 | hle/service/ns/system_update_interface.h | ||
| 788 | hle/service/ns/vulnerability_manager_interface.cpp | ||
| 789 | hle/service/ns/vulnerability_manager_interface.h | ||
| 751 | hle/service/nvdrv/core/container.cpp | 790 | hle/service/nvdrv/core/container.cpp |
| 752 | hle/service/nvdrv/core/container.h | 791 | hle/service/nvdrv/core/container.h |
| 753 | hle/service/nvdrv/core/heap_mapper.cpp | 792 | hle/service/nvdrv/core/heap_mapper.cpp |
| @@ -800,14 +839,14 @@ add_library(core STATIC | |||
| 800 | hle/service/nvnflinger/consumer_base.cpp | 839 | hle/service/nvnflinger/consumer_base.cpp |
| 801 | hle/service/nvnflinger/consumer_base.h | 840 | hle/service/nvnflinger/consumer_base.h |
| 802 | hle/service/nvnflinger/consumer_listener.h | 841 | hle/service/nvnflinger/consumer_listener.h |
| 803 | hle/service/nvnflinger/fb_share_buffer_manager.cpp | ||
| 804 | hle/service/nvnflinger/fb_share_buffer_manager.h | ||
| 805 | hle/service/nvnflinger/graphic_buffer_producer.cpp | 842 | hle/service/nvnflinger/graphic_buffer_producer.cpp |
| 806 | hle/service/nvnflinger/graphic_buffer_producer.h | 843 | hle/service/nvnflinger/graphic_buffer_producer.h |
| 807 | hle/service/nvnflinger/hos_binder_driver_server.cpp | ||
| 808 | hle/service/nvnflinger/hos_binder_driver_server.h | ||
| 809 | hle/service/nvnflinger/hardware_composer.cpp | 844 | hle/service/nvnflinger/hardware_composer.cpp |
| 810 | hle/service/nvnflinger/hardware_composer.h | 845 | hle/service/nvnflinger/hardware_composer.h |
| 846 | hle/service/nvnflinger/hos_binder_driver.cpp | ||
| 847 | hle/service/nvnflinger/hos_binder_driver.h | ||
| 848 | hle/service/nvnflinger/hos_binder_driver_server.cpp | ||
| 849 | hle/service/nvnflinger/hos_binder_driver_server.h | ||
| 811 | hle/service/nvnflinger/hwc_layer.h | 850 | hle/service/nvnflinger/hwc_layer.h |
| 812 | hle/service/nvnflinger/nvnflinger.cpp | 851 | hle/service/nvnflinger/nvnflinger.cpp |
| 813 | hle/service/nvnflinger/nvnflinger.h | 852 | hle/service/nvnflinger/nvnflinger.h |
| @@ -815,6 +854,8 @@ add_library(core STATIC | |||
| 815 | hle/service/nvnflinger/pixel_format.h | 854 | hle/service/nvnflinger/pixel_format.h |
| 816 | hle/service/nvnflinger/producer_listener.h | 855 | hle/service/nvnflinger/producer_listener.h |
| 817 | hle/service/nvnflinger/status.h | 856 | hle/service/nvnflinger/status.h |
| 857 | hle/service/nvnflinger/surface_flinger.cpp | ||
| 858 | hle/service/nvnflinger/surface_flinger.h | ||
| 818 | hle/service/nvnflinger/ui/fence.h | 859 | hle/service/nvnflinger/ui/fence.h |
| 819 | hle/service/nvnflinger/ui/graphic_buffer.cpp | 860 | hle/service/nvnflinger/ui/graphic_buffer.cpp |
| 820 | hle/service/nvnflinger/ui/graphic_buffer.h | 861 | hle/service/nvnflinger/ui/graphic_buffer.h |
| @@ -831,11 +872,11 @@ add_library(core STATIC | |||
| 831 | hle/service/omm/power_state_interface.h | 872 | hle/service/omm/power_state_interface.h |
| 832 | hle/service/os/event.cpp | 873 | hle/service/os/event.cpp |
| 833 | hle/service/os/event.h | 874 | hle/service/os/event.h |
| 875 | hle/service/os/multi_wait.cpp | ||
| 876 | hle/service/os/multi_wait.h | ||
| 834 | hle/service/os/multi_wait_holder.cpp | 877 | hle/service/os/multi_wait_holder.cpp |
| 835 | hle/service/os/multi_wait_holder.h | 878 | hle/service/os/multi_wait_holder.h |
| 836 | hle/service/os/multi_wait_utils.h | 879 | hle/service/os/multi_wait_utils.h |
| 837 | hle/service/os/multi_wait.cpp | ||
| 838 | hle/service/os/multi_wait.h | ||
| 839 | hle/service/os/mutex.cpp | 880 | hle/service/os/mutex.cpp |
| 840 | hle/service/os/mutex.h | 881 | hle/service/os/mutex.h |
| 841 | hle/service/pcie/pcie.cpp | 882 | hle/service/pcie/pcie.cpp |
| @@ -873,15 +914,17 @@ add_library(core STATIC | |||
| 873 | hle/service/psc/time/common.cpp | 914 | hle/service/psc/time/common.cpp |
| 874 | hle/service/psc/time/common.h | 915 | hle/service/psc/time/common.h |
| 875 | hle/service/psc/time/errors.h | 916 | hle/service/psc/time/errors.h |
| 876 | hle/service/psc/time/shared_memory.cpp | ||
| 877 | hle/service/psc/time/shared_memory.h | ||
| 878 | hle/service/psc/time/static.cpp | ||
| 879 | hle/service/psc/time/static.h | ||
| 880 | hle/service/psc/time/manager.h | 917 | hle/service/psc/time/manager.h |
| 918 | hle/service/psc/time/power_state_request_manager.cpp | ||
| 919 | hle/service/psc/time/power_state_request_manager.h | ||
| 881 | hle/service/psc/time/power_state_service.cpp | 920 | hle/service/psc/time/power_state_service.cpp |
| 882 | hle/service/psc/time/power_state_service.h | 921 | hle/service/psc/time/power_state_service.h |
| 883 | hle/service/psc/time/service_manager.cpp | 922 | hle/service/psc/time/service_manager.cpp |
| 884 | hle/service/psc/time/service_manager.h | 923 | hle/service/psc/time/service_manager.h |
| 924 | hle/service/psc/time/shared_memory.cpp | ||
| 925 | hle/service/psc/time/shared_memory.h | ||
| 926 | hle/service/psc/time/static.cpp | ||
| 927 | hle/service/psc/time/static.h | ||
| 885 | hle/service/psc/time/steady_clock.cpp | 928 | hle/service/psc/time/steady_clock.cpp |
| 886 | hle/service/psc/time/steady_clock.h | 929 | hle/service/psc/time/steady_clock.h |
| 887 | hle/service/psc/time/system_clock.cpp | 930 | hle/service/psc/time/system_clock.cpp |
| @@ -890,8 +933,6 @@ add_library(core STATIC | |||
| 890 | hle/service/psc/time/time_zone.h | 933 | hle/service/psc/time/time_zone.h |
| 891 | hle/service/psc/time/time_zone_service.cpp | 934 | hle/service/psc/time/time_zone_service.cpp |
| 892 | hle/service/psc/time/time_zone_service.h | 935 | hle/service/psc/time/time_zone_service.h |
| 893 | hle/service/psc/time/power_state_request_manager.cpp | ||
| 894 | hle/service/psc/time/power_state_request_manager.h | ||
| 895 | hle/service/ptm/psm.cpp | 936 | hle/service/ptm/psm.cpp |
| 896 | hle/service/ptm/psm.h | 937 | hle/service/ptm/psm.h |
| 897 | hle/service/ptm/ptm.cpp | 938 | hle/service/ptm/ptm.cpp |
| @@ -908,19 +949,21 @@ add_library(core STATIC | |||
| 908 | hle/service/server_manager.h | 949 | hle/service/server_manager.h |
| 909 | hle/service/service.cpp | 950 | hle/service/service.cpp |
| 910 | hle/service/service.h | 951 | hle/service/service.h |
| 952 | hle/service/services.cpp | ||
| 953 | hle/service/services.h | ||
| 954 | hle/service/set/factory_settings_server.cpp | ||
| 955 | hle/service/set/factory_settings_server.h | ||
| 956 | hle/service/set/firmware_debug_settings_server.cpp | ||
| 957 | hle/service/set/firmware_debug_settings_server.h | ||
| 958 | hle/service/set/key_code_map.h | ||
| 911 | hle/service/set/setting_formats/appln_settings.cpp | 959 | hle/service/set/setting_formats/appln_settings.cpp |
| 912 | hle/service/set/setting_formats/appln_settings.h | 960 | hle/service/set/setting_formats/appln_settings.h |
| 913 | hle/service/set/setting_formats/device_settings.cpp | 961 | hle/service/set/setting_formats/device_settings.cpp |
| 914 | hle/service/set/setting_formats/device_settings.h | 962 | hle/service/set/setting_formats/device_settings.h |
| 915 | hle/service/set/setting_formats/system_settings.cpp | ||
| 916 | hle/service/set/setting_formats/system_settings.h | ||
| 917 | hle/service/set/setting_formats/private_settings.cpp | 963 | hle/service/set/setting_formats/private_settings.cpp |
| 918 | hle/service/set/setting_formats/private_settings.h | 964 | hle/service/set/setting_formats/private_settings.h |
| 919 | hle/service/set/factory_settings_server.cpp | 965 | hle/service/set/setting_formats/system_settings.cpp |
| 920 | hle/service/set/factory_settings_server.h | 966 | hle/service/set/setting_formats/system_settings.h |
| 921 | hle/service/set/firmware_debug_settings_server.cpp | ||
| 922 | hle/service/set/firmware_debug_settings_server.h | ||
| 923 | hle/service/set/key_code_map.h | ||
| 924 | hle/service/set/settings.cpp | 967 | hle/service/set/settings.cpp |
| 925 | hle/service/set/settings.h | 968 | hle/service/set/settings.h |
| 926 | hle/service/set/settings_server.cpp | 969 | hle/service/set/settings_server.cpp |
| @@ -955,30 +998,36 @@ add_library(core STATIC | |||
| 955 | hle/service/ssl/ssl_backend.h | 998 | hle/service/ssl/ssl_backend.h |
| 956 | hle/service/usb/usb.cpp | 999 | hle/service/usb/usb.cpp |
| 957 | hle/service/usb/usb.h | 1000 | hle/service/usb/usb.h |
| 958 | hle/service/vi/display/vi_display.cpp | ||
| 959 | hle/service/vi/display/vi_display.h | ||
| 960 | hle/service/vi/layer/vi_layer.cpp | ||
| 961 | hle/service/vi/layer/vi_layer.h | ||
| 962 | hle/service/vi/application_display_service.cpp | 1001 | hle/service/vi/application_display_service.cpp |
| 963 | hle/service/vi/application_display_service.h | 1002 | hle/service/vi/application_display_service.h |
| 964 | hle/service/vi/application_root_service.cpp | 1003 | hle/service/vi/application_root_service.cpp |
| 965 | hle/service/vi/application_root_service.h | 1004 | hle/service/vi/application_root_service.h |
| 966 | hle/service/vi/hos_binder_driver.cpp | 1005 | hle/service/vi/conductor.cpp |
| 967 | hle/service/vi/hos_binder_driver.h | 1006 | hle/service/vi/conductor.h |
| 1007 | hle/service/vi/container.cpp | ||
| 1008 | hle/service/vi/container.h | ||
| 1009 | hle/service/vi/display.h | ||
| 1010 | hle/service/vi/display_list.h | ||
| 1011 | hle/service/vi/layer.h | ||
| 1012 | hle/service/vi/layer_list.h | ||
| 968 | hle/service/vi/manager_display_service.cpp | 1013 | hle/service/vi/manager_display_service.cpp |
| 969 | hle/service/vi/manager_display_service.h | 1014 | hle/service/vi/manager_display_service.h |
| 970 | hle/service/vi/manager_root_service.cpp | 1015 | hle/service/vi/manager_root_service.cpp |
| 971 | hle/service/vi/manager_root_service.h | 1016 | hle/service/vi/manager_root_service.h |
| 972 | hle/service/vi/service_creator.cpp | 1017 | hle/service/vi/service_creator.cpp |
| 973 | hle/service/vi/service_creator.h | 1018 | hle/service/vi/service_creator.h |
| 1019 | hle/service/vi/shared_buffer_manager.cpp | ||
| 1020 | hle/service/vi/shared_buffer_manager.h | ||
| 974 | hle/service/vi/system_display_service.cpp | 1021 | hle/service/vi/system_display_service.cpp |
| 975 | hle/service/vi/system_display_service.h | 1022 | hle/service/vi/system_display_service.h |
| 976 | hle/service/vi/system_root_service.cpp | 1023 | hle/service/vi/system_root_service.cpp |
| 977 | hle/service/vi/system_root_service.h | 1024 | hle/service/vi/system_root_service.h |
| 978 | hle/service/vi/vi_results.h | ||
| 979 | hle/service/vi/vi_types.h | ||
| 980 | hle/service/vi/vi.cpp | 1025 | hle/service/vi/vi.cpp |
| 981 | hle/service/vi/vi.h | 1026 | hle/service/vi/vi.h |
| 1027 | hle/service/vi/vi_results.h | ||
| 1028 | hle/service/vi/vi_types.h | ||
| 1029 | hle/service/vi/vsync_manager.cpp | ||
| 1030 | hle/service/vi/vsync_manager.h | ||
| 982 | internal_network/network.cpp | 1031 | internal_network/network.cpp |
| 983 | internal_network/network.h | 1032 | internal_network/network.h |
| 984 | internal_network/network_interface.cpp | 1033 | internal_network/network_interface.cpp |
diff --git a/src/core/core.cpp b/src/core/core.cpp index bd5f11d53..9e8936728 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #include "core/hle/service/psc/time/system_clock.h" | 47 | #include "core/hle/service/psc/time/system_clock.h" |
| 48 | #include "core/hle/service/psc/time/time_zone_service.h" | 48 | #include "core/hle/service/psc/time/time_zone_service.h" |
| 49 | #include "core/hle/service/service.h" | 49 | #include "core/hle/service/service.h" |
| 50 | #include "core/hle/service/services.h" | ||
| 50 | #include "core/hle/service/set/system_settings_server.h" | 51 | #include "core/hle/service/set/system_settings_server.h" |
| 51 | #include "core/hle/service/sm/sm.h" | 52 | #include "core/hle/service/sm/sm.h" |
| 52 | #include "core/internal_network/network.h" | 53 | #include "core/internal_network/network.h" |
| @@ -310,7 +311,8 @@ struct System::Impl { | |||
| 310 | audio_core = std::make_unique<AudioCore::AudioCore>(system); | 311 | audio_core = std::make_unique<AudioCore::AudioCore>(system); |
| 311 | 312 | ||
| 312 | service_manager = std::make_shared<Service::SM::ServiceManager>(kernel); | 313 | service_manager = std::make_shared<Service::SM::ServiceManager>(kernel); |
| 313 | services = std::make_unique<Service::Services>(service_manager, system); | 314 | services = |
| 315 | std::make_unique<Service::Services>(service_manager, system, stop_event.get_token()); | ||
| 314 | 316 | ||
| 315 | is_powered_on = true; | 317 | is_powered_on = true; |
| 316 | exit_locked = false; | 318 | exit_locked = false; |
| @@ -458,11 +460,10 @@ struct System::Impl { | |||
| 458 | gpu_core->NotifyShutdown(); | 460 | gpu_core->NotifyShutdown(); |
| 459 | } | 461 | } |
| 460 | 462 | ||
| 463 | stop_event.request_stop(); | ||
| 464 | core_timing.SyncPause(false); | ||
| 461 | Network::CancelPendingSocketOperations(); | 465 | Network::CancelPendingSocketOperations(); |
| 462 | kernel.SuspendEmulation(true); | 466 | kernel.SuspendEmulation(true); |
| 463 | if (services) { | ||
| 464 | services->KillNVNFlinger(); | ||
| 465 | } | ||
| 466 | kernel.CloseServices(); | 467 | kernel.CloseServices(); |
| 467 | kernel.ShutdownCores(); | 468 | kernel.ShutdownCores(); |
| 468 | applet_manager.Reset(); | 469 | applet_manager.Reset(); |
| @@ -480,6 +481,7 @@ struct System::Impl { | |||
| 480 | cpu_manager.Shutdown(); | 481 | cpu_manager.Shutdown(); |
| 481 | debugger.reset(); | 482 | debugger.reset(); |
| 482 | kernel.Shutdown(); | 483 | kernel.Shutdown(); |
| 484 | stop_event = {}; | ||
| 483 | Network::RestartSocketOperations(); | 485 | Network::RestartSocketOperations(); |
| 484 | 486 | ||
| 485 | if (auto room_member = room_network.GetRoomMember().lock()) { | 487 | if (auto room_member = room_network.GetRoomMember().lock()) { |
| @@ -615,6 +617,7 @@ struct System::Impl { | |||
| 615 | 617 | ||
| 616 | ExecuteProgramCallback execute_program_callback; | 618 | ExecuteProgramCallback execute_program_callback; |
| 617 | ExitCallback exit_callback; | 619 | ExitCallback exit_callback; |
| 620 | std::stop_source stop_event; | ||
| 618 | 621 | ||
| 619 | std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{}; | 622 | std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{}; |
| 620 | std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_cpu{}; | 623 | std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_cpu{}; |
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index 7a5c22f78..9b1c77387 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp | |||
| @@ -199,10 +199,10 @@ void CpuManager::RunThread(std::stop_token token, std::size_t core) { | |||
| 199 | data.host_context = Common::Fiber::ThreadToFiber(); | 199 | data.host_context = Common::Fiber::ThreadToFiber(); |
| 200 | 200 | ||
| 201 | // Cleanup | 201 | // Cleanup |
| 202 | SCOPE_EXIT({ | 202 | SCOPE_EXIT { |
| 203 | data.host_context->Exit(); | 203 | data.host_context->Exit(); |
| 204 | MicroProfileOnThreadExit(); | 204 | MicroProfileOnThreadExit(); |
| 205 | }); | 205 | }; |
| 206 | 206 | ||
| 207 | // Running | 207 | // Running |
| 208 | if (!gpu_barrier->Sync(token)) { | 208 | if (!gpu_barrier->Sync(token)) { |
diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc index 6dfee806c..37c1e69c3 100644 --- a/src/core/device_memory_manager.inc +++ b/src/core/device_memory_manager.inc | |||
| @@ -391,12 +391,12 @@ void DeviceMemoryManager<Traits>::WalkBlock(DAddr addr, std::size_t size, auto o | |||
| 391 | std::min((next_pages << Memory::YUZU_PAGEBITS) - page_offset, remaining_size); | 391 | std::min((next_pages << Memory::YUZU_PAGEBITS) - page_offset, remaining_size); |
| 392 | const auto current_vaddr = | 392 | const auto current_vaddr = |
| 393 | static_cast<u64>((page_index << Memory::YUZU_PAGEBITS) + page_offset); | 393 | static_cast<u64>((page_index << Memory::YUZU_PAGEBITS) + page_offset); |
| 394 | SCOPE_EXIT({ | 394 | SCOPE_EXIT{ |
| 395 | page_index += next_pages; | 395 | page_index += next_pages; |
| 396 | page_offset = 0; | 396 | page_offset = 0; |
| 397 | increment(copy_amount); | 397 | increment(copy_amount); |
| 398 | remaining_size -= copy_amount; | 398 | remaining_size -= copy_amount; |
| 399 | }); | 399 | }; |
| 400 | 400 | ||
| 401 | auto phys_addr = compressed_physical_ptr[page_index]; | 401 | auto phys_addr = compressed_physical_ptr[page_index]; |
| 402 | if (phys_addr == 0) { | 402 | if (phys_addr == 0) { |
diff --git a/src/core/file_sys/fs_directory.h b/src/core/file_sys/fs_directory.h index 25c9cb18a..3f90abb8f 100644 --- a/src/core/file_sys/fs_directory.h +++ b/src/core/file_sys/fs_directory.h | |||
| @@ -3,6 +3,10 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <string_view> | ||
| 7 | #include "common/common_funcs.h" | ||
| 8 | #include "common/common_types.h" | ||
| 9 | |||
| 6 | namespace FileSys { | 10 | namespace FileSys { |
| 7 | 11 | ||
| 8 | constexpr inline size_t EntryNameLengthMax = 0x300; | 12 | constexpr inline size_t EntryNameLengthMax = 0x300; |
diff --git a/src/core/file_sys/fs_path_utility.h b/src/core/file_sys/fs_path_utility.h index e9011d065..5643141f9 100644 --- a/src/core/file_sys/fs_path_utility.h +++ b/src/core/file_sys/fs_path_utility.h | |||
| @@ -447,7 +447,7 @@ public: | |||
| 447 | char* replacement_path = nullptr; | 447 | char* replacement_path = nullptr; |
| 448 | size_t replacement_path_size = 0; | 448 | size_t replacement_path_size = 0; |
| 449 | 449 | ||
| 450 | SCOPE_EXIT({ | 450 | SCOPE_EXIT { |
| 451 | if (replacement_path != nullptr) { | 451 | if (replacement_path != nullptr) { |
| 452 | if (std::is_constant_evaluated()) { | 452 | if (std::is_constant_evaluated()) { |
| 453 | delete[] replacement_path; | 453 | delete[] replacement_path; |
| @@ -455,7 +455,7 @@ public: | |||
| 455 | Deallocate(replacement_path, replacement_path_size); | 455 | Deallocate(replacement_path, replacement_path_size); |
| 456 | } | 456 | } |
| 457 | } | 457 | } |
| 458 | }); | 458 | }; |
| 459 | 459 | ||
| 460 | // Perform path replacement, if necessary | 460 | // Perform path replacement, if necessary |
| 461 | if (IsParentDirectoryPathReplacementNeeded(cur_path)) { | 461 | if (IsParentDirectoryPathReplacementNeeded(cur_path)) { |
| @@ -1102,8 +1102,8 @@ public: | |||
| 1102 | R_SUCCEED(); | 1102 | R_SUCCEED(); |
| 1103 | } | 1103 | } |
| 1104 | 1104 | ||
| 1105 | static Result Normalize(char* dst, size_t dst_size, const char* path, size_t path_len, | 1105 | static constexpr Result Normalize(char* dst, size_t dst_size, const char* path, size_t path_len, |
| 1106 | const PathFlags& flags) { | 1106 | const PathFlags& flags) { |
| 1107 | // Use StringTraits names for remainder of scope | 1107 | // Use StringTraits names for remainder of scope |
| 1108 | using namespace StringTraits; | 1108 | using namespace StringTraits; |
| 1109 | 1109 | ||
| @@ -1199,7 +1199,7 @@ public: | |||
| 1199 | const size_t replaced_src_len = path_len - (src - path); | 1199 | const size_t replaced_src_len = path_len - (src - path); |
| 1200 | 1200 | ||
| 1201 | char* replaced_src = nullptr; | 1201 | char* replaced_src = nullptr; |
| 1202 | SCOPE_EXIT({ | 1202 | SCOPE_EXIT { |
| 1203 | if (replaced_src != nullptr) { | 1203 | if (replaced_src != nullptr) { |
| 1204 | if (std::is_constant_evaluated()) { | 1204 | if (std::is_constant_evaluated()) { |
| 1205 | delete[] replaced_src; | 1205 | delete[] replaced_src; |
| @@ -1207,7 +1207,7 @@ public: | |||
| 1207 | Deallocate(replaced_src, replaced_src_len); | 1207 | Deallocate(replaced_src, replaced_src_len); |
| 1208 | } | 1208 | } |
| 1209 | } | 1209 | } |
| 1210 | }); | 1210 | }; |
| 1211 | 1211 | ||
| 1212 | if (std::is_constant_evaluated()) { | 1212 | if (std::is_constant_evaluated()) { |
| 1213 | replaced_src = new char[replaced_src_len]; | 1213 | replaced_src = new char[replaced_src_len]; |
diff --git a/src/core/file_sys/fssystem/fssystem_aes_xts_storage.h b/src/core/file_sys/fssystem/fssystem_aes_xts_storage.h index f342efb57..0e83ca1b9 100644 --- a/src/core/file_sys/fssystem/fssystem_aes_xts_storage.h +++ b/src/core/file_sys/fssystem/fssystem_aes_xts_storage.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <mutex> | ||
| 6 | #include <optional> | 7 | #include <optional> |
| 7 | 8 | ||
| 8 | #include "core/crypto/aes_util.h" | 9 | #include "core/crypto/aes_util.h" |
diff --git a/src/core/file_sys/fssystem/fssystem_hierarchical_sha256_storage.cpp b/src/core/file_sys/fssystem/fssystem_hierarchical_sha256_storage.cpp index caea0b8f8..a68fd973c 100644 --- a/src/core/file_sys/fssystem/fssystem_hierarchical_sha256_storage.cpp +++ b/src/core/file_sys/fssystem/fssystem_hierarchical_sha256_storage.cpp | |||
| @@ -36,7 +36,9 @@ Result HierarchicalSha256Storage::Initialize(VirtualFile* base_storages, s32 lay | |||
| 36 | // Get the base storage size. | 36 | // Get the base storage size. |
| 37 | m_base_storage_size = base_storages[2]->GetSize(); | 37 | m_base_storage_size = base_storages[2]->GetSize(); |
| 38 | { | 38 | { |
| 39 | auto size_guard = SCOPE_GUARD({ m_base_storage_size = 0; }); | 39 | auto size_guard = SCOPE_GUARD { |
| 40 | m_base_storage_size = 0; | ||
| 41 | }; | ||
| 40 | R_UNLESS(m_base_storage_size <= static_cast<s64>(HashSize) | 42 | R_UNLESS(m_base_storage_size <= static_cast<s64>(HashSize) |
| 41 | << m_log_size_ratio << m_log_size_ratio, | 43 | << m_log_size_ratio << m_log_size_ratio, |
| 42 | ResultHierarchicalSha256BaseStorageTooLarge); | 44 | ResultHierarchicalSha256BaseStorageTooLarge); |
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp index ae4e441c9..289969cc4 100644 --- a/src/core/file_sys/program_metadata.cpp +++ b/src/core/file_sys/program_metadata.cpp | |||
| @@ -98,7 +98,9 @@ Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) { | |||
| 98 | 98 | ||
| 99 | Loader::ResultStatus ProgramMetadata::Reload(VirtualFile file) { | 99 | Loader::ResultStatus ProgramMetadata::Reload(VirtualFile file) { |
| 100 | const u64 original_program_id = aci_header.title_id; | 100 | const u64 original_program_id = aci_header.title_id; |
| 101 | SCOPE_EXIT({ aci_header.title_id = original_program_id; }); | 101 | SCOPE_EXIT { |
| 102 | aci_header.title_id = original_program_id; | ||
| 103 | }; | ||
| 102 | 104 | ||
| 103 | return this->Load(file); | 105 | return this->Load(file); |
| 104 | } | 106 | } |
diff --git a/src/core/file_sys/system_archive/shared_font.cpp b/src/core/file_sys/system_archive/shared_font.cpp index deb52069d..9ea16aa59 100644 --- a/src/core/file_sys/system_archive/shared_font.cpp +++ b/src/core/file_sys/system_archive/shared_font.cpp | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include "core/file_sys/system_archive/data/font_standard.h" | 9 | #include "core/file_sys/system_archive/data/font_standard.h" |
| 10 | #include "core/file_sys/system_archive/shared_font.h" | 10 | #include "core/file_sys/system_archive/shared_font.h" |
| 11 | #include "core/file_sys/vfs/vfs_vector.h" | 11 | #include "core/file_sys/vfs/vfs_vector.h" |
| 12 | #include "core/hle/service/ns/iplatform_service_manager.h" | 12 | #include "core/hle/service/ns/platform_service_manager.h" |
| 13 | 13 | ||
| 14 | namespace FileSys::SystemArchive { | 14 | namespace FileSys::SystemArchive { |
| 15 | 15 | ||
diff --git a/src/core/hle/kernel/k_client_session.cpp b/src/core/hle/kernel/k_client_session.cpp index 472e8571c..3e01e3b67 100644 --- a/src/core/hle/kernel/k_client_session.cpp +++ b/src/core/hle/kernel/k_client_session.cpp | |||
| @@ -24,7 +24,9 @@ Result KClientSession::SendSyncRequest(uintptr_t address, size_t size) { | |||
| 24 | // Create a session request. | 24 | // Create a session request. |
| 25 | KSessionRequest* request = KSessionRequest::Create(m_kernel); | 25 | KSessionRequest* request = KSessionRequest::Create(m_kernel); |
| 26 | R_UNLESS(request != nullptr, ResultOutOfResource); | 26 | R_UNLESS(request != nullptr, ResultOutOfResource); |
| 27 | SCOPE_EXIT({ request->Close(); }); | 27 | SCOPE_EXIT { |
| 28 | request->Close(); | ||
| 29 | }; | ||
| 28 | 30 | ||
| 29 | // Initialize the request. | 31 | // Initialize the request. |
| 30 | request->Initialize(nullptr, address, size); | 32 | request->Initialize(nullptr, address, size); |
| @@ -37,7 +39,9 @@ Result KClientSession::SendAsyncRequest(KEvent* event, uintptr_t address, size_t | |||
| 37 | // Create a session request. | 39 | // Create a session request. |
| 38 | KSessionRequest* request = KSessionRequest::Create(m_kernel); | 40 | KSessionRequest* request = KSessionRequest::Create(m_kernel); |
| 39 | R_UNLESS(request != nullptr, ResultOutOfResource); | 41 | R_UNLESS(request != nullptr, ResultOutOfResource); |
| 40 | SCOPE_EXIT({ request->Close(); }); | 42 | SCOPE_EXIT { |
| 43 | request->Close(); | ||
| 44 | }; | ||
| 41 | 45 | ||
| 42 | // Initialize the request. | 46 | // Initialize the request. |
| 43 | request->Initialize(event, address, size); | 47 | request->Initialize(event, address, size); |
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp index 1dd86fb3c..19cdf4f3a 100644 --- a/src/core/hle/kernel/k_page_table_base.cpp +++ b/src/core/hle/kernel/k_page_table_base.cpp | |||
| @@ -1305,11 +1305,11 @@ Result KPageTableBase::UnmapCodeMemory(KProcessAddress dst_address, KProcessAddr | |||
| 1305 | 1305 | ||
| 1306 | // Ensure that we maintain the instruction cache. | 1306 | // Ensure that we maintain the instruction cache. |
| 1307 | bool reprotected_pages = false; | 1307 | bool reprotected_pages = false; |
| 1308 | SCOPE_EXIT({ | 1308 | SCOPE_EXIT { |
| 1309 | if (reprotected_pages && any_code_pages) { | 1309 | if (reprotected_pages && any_code_pages) { |
| 1310 | InvalidateInstructionCache(m_kernel, this, dst_address, size); | 1310 | InvalidateInstructionCache(m_kernel, this, dst_address, size); |
| 1311 | } | 1311 | } |
| 1312 | }); | 1312 | }; |
| 1313 | 1313 | ||
| 1314 | // Unmap. | 1314 | // Unmap. |
| 1315 | { | 1315 | { |
| @@ -1397,7 +1397,9 @@ Result KPageTableBase::MapInsecureMemory(KProcessAddress address, size_t size) { | |||
| 1397 | // Close the opened pages when we're done with them. | 1397 | // Close the opened pages when we're done with them. |
| 1398 | // If the mapping succeeds, each page will gain an extra reference, otherwise they will be freed | 1398 | // If the mapping succeeds, each page will gain an extra reference, otherwise they will be freed |
| 1399 | // automatically. | 1399 | // automatically. |
| 1400 | SCOPE_EXIT({ pg.Close(); }); | 1400 | SCOPE_EXIT { |
| 1401 | pg.Close(); | ||
| 1402 | }; | ||
| 1401 | 1403 | ||
| 1402 | // Clear all the newly allocated pages. | 1404 | // Clear all the newly allocated pages. |
| 1403 | for (const auto& it : pg) { | 1405 | for (const auto& it : pg) { |
| @@ -1603,7 +1605,9 @@ Result KPageTableBase::AllocateAndMapPagesImpl(PageLinkedList* page_list, KProce | |||
| 1603 | m_kernel.MemoryManager().AllocateAndOpen(std::addressof(pg), num_pages, m_allocate_option)); | 1605 | m_kernel.MemoryManager().AllocateAndOpen(std::addressof(pg), num_pages, m_allocate_option)); |
| 1604 | 1606 | ||
| 1605 | // Ensure that the page group is closed when we're done working with it. | 1607 | // Ensure that the page group is closed when we're done working with it. |
| 1606 | SCOPE_EXIT({ pg.Close(); }); | 1608 | SCOPE_EXIT { |
| 1609 | pg.Close(); | ||
| 1610 | }; | ||
| 1607 | 1611 | ||
| 1608 | // Clear all pages. | 1612 | // Clear all pages. |
| 1609 | for (const auto& it : pg) { | 1613 | for (const auto& it : pg) { |
| @@ -2191,7 +2195,9 @@ Result KPageTableBase::SetHeapSize(KProcessAddress* out, size_t size) { | |||
| 2191 | // Close the opened pages when we're done with them. | 2195 | // Close the opened pages when we're done with them. |
| 2192 | // If the mapping succeeds, each page will gain an extra reference, otherwise they will be freed | 2196 | // If the mapping succeeds, each page will gain an extra reference, otherwise they will be freed |
| 2193 | // automatically. | 2197 | // automatically. |
| 2194 | SCOPE_EXIT({ pg.Close(); }); | 2198 | SCOPE_EXIT { |
| 2199 | pg.Close(); | ||
| 2200 | }; | ||
| 2195 | 2201 | ||
| 2196 | // Clear all the newly allocated pages. | 2202 | // Clear all the newly allocated pages. |
| 2197 | for (const auto& it : pg) { | 2203 | for (const auto& it : pg) { |
| @@ -2592,7 +2598,9 @@ Result KPageTableBase::UnmapIoRegion(KProcessAddress dst_address, KPhysicalAddre | |||
| 2592 | // Temporarily unlock ourselves, so that other operations can occur while we flush the | 2598 | // Temporarily unlock ourselves, so that other operations can occur while we flush the |
| 2593 | // region. | 2599 | // region. |
| 2594 | m_general_lock.Unlock(); | 2600 | m_general_lock.Unlock(); |
| 2595 | SCOPE_EXIT({ m_general_lock.Lock(); }); | 2601 | SCOPE_EXIT { |
| 2602 | m_general_lock.Lock(); | ||
| 2603 | }; | ||
| 2596 | 2604 | ||
| 2597 | // Flush the region. | 2605 | // Flush the region. |
| 2598 | R_ASSERT(FlushDataCache(dst_address, size)); | 2606 | R_ASSERT(FlushDataCache(dst_address, size)); |
| @@ -3311,10 +3319,10 @@ Result KPageTableBase::ReadIoMemoryImpl(KProcessAddress dst_addr, KPhysicalAddre | |||
| 3311 | // Ensure we unmap the io memory when we're done with it. | 3319 | // Ensure we unmap the io memory when we're done with it. |
| 3312 | const KPageProperties unmap_properties = | 3320 | const KPageProperties unmap_properties = |
| 3313 | KPageProperties{KMemoryPermission::None, false, false, DisableMergeAttribute::None}; | 3321 | KPageProperties{KMemoryPermission::None, false, false, DisableMergeAttribute::None}; |
| 3314 | SCOPE_EXIT({ | 3322 | SCOPE_EXIT { |
| 3315 | R_ASSERT(this->Operate(updater.GetPageList(), io_addr, map_size / PageSize, 0, false, | 3323 | R_ASSERT(this->Operate(updater.GetPageList(), io_addr, map_size / PageSize, 0, false, |
| 3316 | unmap_properties, OperationType::Unmap, true)); | 3324 | unmap_properties, OperationType::Unmap, true)); |
| 3317 | }); | 3325 | }; |
| 3318 | 3326 | ||
| 3319 | // Read the memory. | 3327 | // Read the memory. |
| 3320 | const KProcessAddress read_addr = io_addr + (GetInteger(phys_addr) & (PageSize - 1)); | 3328 | const KProcessAddress read_addr = io_addr + (GetInteger(phys_addr) & (PageSize - 1)); |
| @@ -3347,10 +3355,10 @@ Result KPageTableBase::WriteIoMemoryImpl(KPhysicalAddress phys_addr, KProcessAdd | |||
| 3347 | // Ensure we unmap the io memory when we're done with it. | 3355 | // Ensure we unmap the io memory when we're done with it. |
| 3348 | const KPageProperties unmap_properties = | 3356 | const KPageProperties unmap_properties = |
| 3349 | KPageProperties{KMemoryPermission::None, false, false, DisableMergeAttribute::None}; | 3357 | KPageProperties{KMemoryPermission::None, false, false, DisableMergeAttribute::None}; |
| 3350 | SCOPE_EXIT({ | 3358 | SCOPE_EXIT { |
| 3351 | R_ASSERT(this->Operate(updater.GetPageList(), io_addr, map_size / PageSize, 0, false, | 3359 | R_ASSERT(this->Operate(updater.GetPageList(), io_addr, map_size / PageSize, 0, false, |
| 3352 | unmap_properties, OperationType::Unmap, true)); | 3360 | unmap_properties, OperationType::Unmap, true)); |
| 3353 | }); | 3361 | }; |
| 3354 | 3362 | ||
| 3355 | // Write the memory. | 3363 | // Write the memory. |
| 3356 | const KProcessAddress write_addr = io_addr + (GetInteger(phys_addr) & (PageSize - 1)); | 3364 | const KProcessAddress write_addr = io_addr + (GetInteger(phys_addr) & (PageSize - 1)); |
| @@ -4491,14 +4499,14 @@ Result KPageTableBase::SetupForIpcServer(KProcessAddress* out_addr, size_t size, | |||
| 4491 | 4499 | ||
| 4492 | // If the partial pages are mapped, an extra reference will have been opened. Otherwise, they'll | 4500 | // If the partial pages are mapped, an extra reference will have been opened. Otherwise, they'll |
| 4493 | // free on scope exit. | 4501 | // free on scope exit. |
| 4494 | SCOPE_EXIT({ | 4502 | SCOPE_EXIT { |
| 4495 | if (start_partial_page != 0) { | 4503 | if (start_partial_page != 0) { |
| 4496 | m_kernel.MemoryManager().Close(start_partial_page, 1); | 4504 | m_kernel.MemoryManager().Close(start_partial_page, 1); |
| 4497 | } | 4505 | } |
| 4498 | if (end_partial_page != 0) { | 4506 | if (end_partial_page != 0) { |
| 4499 | m_kernel.MemoryManager().Close(end_partial_page, 1); | 4507 | m_kernel.MemoryManager().Close(end_partial_page, 1); |
| 4500 | } | 4508 | } |
| 4501 | }); | 4509 | }; |
| 4502 | 4510 | ||
| 4503 | ON_RESULT_FAILURE { | 4511 | ON_RESULT_FAILURE { |
| 4504 | if (cur_mapped_addr != dst_addr) { | 4512 | if (cur_mapped_addr != dst_addr) { |
| @@ -5166,10 +5174,10 @@ Result KPageTableBase::MapPhysicalMemory(KProcessAddress address, size_t size) { | |||
| 5166 | GetCurrentProcess(m_kernel).GetId(), m_heap_fill_value)); | 5174 | GetCurrentProcess(m_kernel).GetId(), m_heap_fill_value)); |
| 5167 | 5175 | ||
| 5168 | // If we fail in the next bit (or retry), we need to cleanup the pages. | 5176 | // If we fail in the next bit (or retry), we need to cleanup the pages. |
| 5169 | auto pg_guard = SCOPE_GUARD({ | 5177 | auto pg_guard = SCOPE_GUARD { |
| 5170 | pg.OpenFirst(); | 5178 | pg.OpenFirst(); |
| 5171 | pg.Close(); | 5179 | pg.Close(); |
| 5172 | }); | 5180 | }; |
| 5173 | 5181 | ||
| 5174 | // Map the memory. | 5182 | // Map the memory. |
| 5175 | { | 5183 | { |
| @@ -5694,7 +5702,9 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a | |||
| 5694 | 5702 | ||
| 5695 | // Ensure that any pages we track are closed on exit. | 5703 | // Ensure that any pages we track are closed on exit. |
| 5696 | KPageGroup pages_to_close(m_kernel, this->GetBlockInfoManager()); | 5704 | KPageGroup pages_to_close(m_kernel, this->GetBlockInfoManager()); |
| 5697 | SCOPE_EXIT({ pages_to_close.CloseAndReset(); }); | 5705 | SCOPE_EXIT { |
| 5706 | pages_to_close.CloseAndReset(); | ||
| 5707 | }; | ||
| 5698 | 5708 | ||
| 5699 | // Make a page group representing the region to unmap. | 5709 | // Make a page group representing the region to unmap. |
| 5700 | this->MakePageGroup(pages_to_close, virt_addr, num_pages); | 5710 | this->MakePageGroup(pages_to_close, virt_addr, num_pages); |
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 1bcc42890..cb9a11a63 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp | |||
| @@ -77,7 +77,9 @@ Result TerminateChildren(KernelCore& kernel, KProcess* process, | |||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | // Terminate and close the thread. | 79 | // Terminate and close the thread. |
| 80 | SCOPE_EXIT({ cur_child->Close(); }); | 80 | SCOPE_EXIT { |
| 81 | cur_child->Close(); | ||
| 82 | }; | ||
| 81 | 83 | ||
| 82 | if (const Result terminate_result = cur_child->Terminate(); | 84 | if (const Result terminate_result = cur_child->Terminate(); |
| 83 | ResultTerminationRequested == terminate_result) { | 85 | ResultTerminationRequested == terminate_result) { |
| @@ -466,11 +468,11 @@ void KProcess::DoWorkerTaskImpl() { | |||
| 466 | 468 | ||
| 467 | Result KProcess::StartTermination() { | 469 | Result KProcess::StartTermination() { |
| 468 | // Finalize the handle table when we're done, if the process isn't immortal. | 470 | // Finalize the handle table when we're done, if the process isn't immortal. |
| 469 | SCOPE_EXIT({ | 471 | SCOPE_EXIT { |
| 470 | if (!m_is_immortal) { | 472 | if (!m_is_immortal) { |
| 471 | this->FinalizeHandleTable(); | 473 | this->FinalizeHandleTable(); |
| 472 | } | 474 | } |
| 473 | }); | 475 | }; |
| 474 | 476 | ||
| 475 | // Terminate child threads other than the current one. | 477 | // Terminate child threads other than the current one. |
| 476 | R_RETURN(TerminateChildren(m_kernel, this, GetCurrentThreadPointer(m_kernel))); | 478 | R_RETURN(TerminateChildren(m_kernel, this, GetCurrentThreadPointer(m_kernel))); |
| @@ -964,7 +966,9 @@ Result KProcess::Run(s32 priority, size_t stack_size) { | |||
| 964 | // Create a new thread for the process. | 966 | // Create a new thread for the process. |
| 965 | KThread* main_thread = KThread::Create(m_kernel); | 967 | KThread* main_thread = KThread::Create(m_kernel); |
| 966 | R_UNLESS(main_thread != nullptr, ResultOutOfResource); | 968 | R_UNLESS(main_thread != nullptr, ResultOutOfResource); |
| 967 | SCOPE_EXIT({ main_thread->Close(); }); | 969 | SCOPE_EXIT { |
| 970 | main_thread->Close(); | ||
| 971 | }; | ||
| 968 | 972 | ||
| 969 | // Initialize the thread. | 973 | // Initialize the thread. |
| 970 | R_TRY(KThread::InitializeUserThread(m_kernel.System(), main_thread, this->GetEntryPoint(), 0, | 974 | R_TRY(KThread::InitializeUserThread(m_kernel.System(), main_thread, this->GetEntryPoint(), 0, |
| @@ -1155,7 +1159,9 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std: | |||
| 1155 | Kernel::CreateResourceLimitForProcess(m_kernel.System(), physical_memory_size); | 1159 | Kernel::CreateResourceLimitForProcess(m_kernel.System(), physical_memory_size); |
| 1156 | 1160 | ||
| 1157 | // Ensure we maintain a clean state on exit. | 1161 | // Ensure we maintain a clean state on exit. |
| 1158 | SCOPE_EXIT({ res_limit->Close(); }); | 1162 | SCOPE_EXIT { |
| 1163 | res_limit->Close(); | ||
| 1164 | }; | ||
| 1159 | 1165 | ||
| 1160 | // Declare flags and code address. | 1166 | // Declare flags and code address. |
| 1161 | Svc::CreateProcessFlag flag{}; | 1167 | Svc::CreateProcessFlag flag{}; |
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index adaabdd6d..40c3323ef 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp | |||
| @@ -651,11 +651,11 @@ Result ReceiveMessage(KernelCore& kernel, bool& recv_list_broken, uint64_t dst_m | |||
| 651 | // Process any special data. | 651 | // Process any special data. |
| 652 | if (src_header.GetHasSpecialHeader()) { | 652 | if (src_header.GetHasSpecialHeader()) { |
| 653 | // After we process, make sure we track whether the receive list is broken. | 653 | // After we process, make sure we track whether the receive list is broken. |
| 654 | SCOPE_EXIT({ | 654 | SCOPE_EXIT { |
| 655 | if (offset > dst_recv_list_idx) { | 655 | if (offset > dst_recv_list_idx) { |
| 656 | recv_list_broken = true; | 656 | recv_list_broken = true; |
| 657 | } | 657 | } |
| 658 | }); | 658 | }; |
| 659 | 659 | ||
| 660 | // Process special data. | 660 | // Process special data. |
| 661 | R_TRY(ProcessMessageSpecialData<false>(offset, dst_process, src_process, src_thread, | 661 | R_TRY(ProcessMessageSpecialData<false>(offset, dst_process, src_process, src_thread, |
| @@ -665,11 +665,11 @@ Result ReceiveMessage(KernelCore& kernel, bool& recv_list_broken, uint64_t dst_m | |||
| 665 | // Process any pointer buffers. | 665 | // Process any pointer buffers. |
| 666 | for (auto i = 0; i < src_header.GetPointerCount(); ++i) { | 666 | for (auto i = 0; i < src_header.GetPointerCount(); ++i) { |
| 667 | // After we process, make sure we track whether the receive list is broken. | 667 | // After we process, make sure we track whether the receive list is broken. |
| 668 | SCOPE_EXIT({ | 668 | SCOPE_EXIT { |
| 669 | if (offset > dst_recv_list_idx) { | 669 | if (offset > dst_recv_list_idx) { |
| 670 | recv_list_broken = true; | 670 | recv_list_broken = true; |
| 671 | } | 671 | } |
| 672 | }); | 672 | }; |
| 673 | 673 | ||
| 674 | R_TRY(ProcessReceiveMessagePointerDescriptors( | 674 | R_TRY(ProcessReceiveMessagePointerDescriptors( |
| 675 | offset, pointer_key, dst_page_table, src_page_table, dst_msg, src_msg, dst_recv_list, | 675 | offset, pointer_key, dst_page_table, src_page_table, dst_msg, src_msg, dst_recv_list, |
| @@ -680,11 +680,11 @@ Result ReceiveMessage(KernelCore& kernel, bool& recv_list_broken, uint64_t dst_m | |||
| 680 | // Process any map alias buffers. | 680 | // Process any map alias buffers. |
| 681 | for (auto i = 0; i < src_header.GetMapAliasCount(); ++i) { | 681 | for (auto i = 0; i < src_header.GetMapAliasCount(); ++i) { |
| 682 | // After we process, make sure we track whether the receive list is broken. | 682 | // After we process, make sure we track whether the receive list is broken. |
| 683 | SCOPE_EXIT({ | 683 | SCOPE_EXIT { |
| 684 | if (offset > dst_recv_list_idx) { | 684 | if (offset > dst_recv_list_idx) { |
| 685 | recv_list_broken = true; | 685 | recv_list_broken = true; |
| 686 | } | 686 | } |
| 687 | }); | 687 | }; |
| 688 | 688 | ||
| 689 | // We process in order send, recv, exch. Buffers after send (recv/exch) are ReadWrite. | 689 | // We process in order send, recv, exch. Buffers after send (recv/exch) are ReadWrite. |
| 690 | const KMemoryPermission perm = (i >= src_header.GetSendCount()) | 690 | const KMemoryPermission perm = (i >= src_header.GetSendCount()) |
| @@ -702,11 +702,11 @@ Result ReceiveMessage(KernelCore& kernel, bool& recv_list_broken, uint64_t dst_m | |||
| 702 | // Process any raw data. | 702 | // Process any raw data. |
| 703 | if (const auto raw_count = src_header.GetRawCount(); raw_count != 0) { | 703 | if (const auto raw_count = src_header.GetRawCount(); raw_count != 0) { |
| 704 | // After we process, make sure we track whether the receive list is broken. | 704 | // After we process, make sure we track whether the receive list is broken. |
| 705 | SCOPE_EXIT({ | 705 | SCOPE_EXIT { |
| 706 | if (offset + raw_count > dst_recv_list_idx) { | 706 | if (offset + raw_count > dst_recv_list_idx) { |
| 707 | recv_list_broken = true; | 707 | recv_list_broken = true; |
| 708 | } | 708 | } |
| 709 | }); | 709 | }; |
| 710 | 710 | ||
| 711 | // Get the offset and size. | 711 | // Get the offset and size. |
| 712 | const size_t offset_words = offset * sizeof(u32); | 712 | const size_t offset_words = offset * sizeof(u32); |
| @@ -1124,7 +1124,9 @@ Result KServerSession::ReceiveRequest(uintptr_t server_message, uintptr_t server | |||
| 1124 | client_thread->Open(); | 1124 | client_thread->Open(); |
| 1125 | } | 1125 | } |
| 1126 | 1126 | ||
| 1127 | SCOPE_EXIT({ client_thread->Close(); }); | 1127 | SCOPE_EXIT { |
| 1128 | client_thread->Close(); | ||
| 1129 | }; | ||
| 1128 | 1130 | ||
| 1129 | // Set the request as our current. | 1131 | // Set the request as our current. |
| 1130 | m_current_request = request; | 1132 | m_current_request = request; |
| @@ -1174,7 +1176,9 @@ Result KServerSession::ReceiveRequest(uintptr_t server_message, uintptr_t server | |||
| 1174 | // Reply to the client. | 1176 | // Reply to the client. |
| 1175 | { | 1177 | { |
| 1176 | // After we reply, close our reference to the request. | 1178 | // After we reply, close our reference to the request. |
| 1177 | SCOPE_EXIT({ request->Close(); }); | 1179 | SCOPE_EXIT { |
| 1180 | request->Close(); | ||
| 1181 | }; | ||
| 1178 | 1182 | ||
| 1179 | // Get the event to check whether the request is async. | 1183 | // Get the event to check whether the request is async. |
| 1180 | if (KEvent* event = request->GetEvent(); event != nullptr) { | 1184 | if (KEvent* event = request->GetEvent(); event != nullptr) { |
| @@ -1236,7 +1240,9 @@ Result KServerSession::SendReply(uintptr_t server_message, uintptr_t server_buff | |||
| 1236 | } | 1240 | } |
| 1237 | 1241 | ||
| 1238 | // Close reference to the request once we're done processing it. | 1242 | // Close reference to the request once we're done processing it. |
| 1239 | SCOPE_EXIT({ request->Close(); }); | 1243 | SCOPE_EXIT { |
| 1244 | request->Close(); | ||
| 1245 | }; | ||
| 1240 | 1246 | ||
| 1241 | // Extract relevant information from the request. | 1247 | // Extract relevant information from the request. |
| 1242 | const uint64_t client_message = request->GetAddress(); | 1248 | const uint64_t client_message = request->GetAddress(); |
| @@ -1394,7 +1400,9 @@ void KServerSession::CleanupRequests() { | |||
| 1394 | } | 1400 | } |
| 1395 | 1401 | ||
| 1396 | // Close a reference to the request once it's cleaned up. | 1402 | // Close a reference to the request once it's cleaned up. |
| 1397 | SCOPE_EXIT({ request->Close(); }); | 1403 | SCOPE_EXIT { |
| 1404 | request->Close(); | ||
| 1405 | }; | ||
| 1398 | 1406 | ||
| 1399 | // Extract relevant information from the request. | 1407 | // Extract relevant information from the request. |
| 1400 | const uint64_t client_message = request->GetAddress(); | 1408 | const uint64_t client_message = request->GetAddress(); |
| @@ -1491,7 +1499,9 @@ void KServerSession::OnClientClosed() { | |||
| 1491 | ASSERT(thread != nullptr); | 1499 | ASSERT(thread != nullptr); |
| 1492 | 1500 | ||
| 1493 | // Ensure that we close the request when done. | 1501 | // Ensure that we close the request when done. |
| 1494 | SCOPE_EXIT({ request->Close(); }); | 1502 | SCOPE_EXIT { |
| 1503 | request->Close(); | ||
| 1504 | }; | ||
| 1495 | 1505 | ||
| 1496 | // If we're terminating, close a reference to the thread and event. | 1506 | // If we're terminating, close a reference to the thread and event. |
| 1497 | if (terminate) { | 1507 | if (terminate) { |
diff --git a/src/core/hle/kernel/k_thread_local_page.cpp b/src/core/hle/kernel/k_thread_local_page.cpp index a632d1634..1952c0083 100644 --- a/src/core/hle/kernel/k_thread_local_page.cpp +++ b/src/core/hle/kernel/k_thread_local_page.cpp | |||
| @@ -21,7 +21,9 @@ Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) { | |||
| 21 | // Allocate a new page. | 21 | // Allocate a new page. |
| 22 | KPageBuffer* page_buf = KPageBuffer::Allocate(kernel); | 22 | KPageBuffer* page_buf = KPageBuffer::Allocate(kernel); |
| 23 | R_UNLESS(page_buf != nullptr, ResultOutOfMemory); | 23 | R_UNLESS(page_buf != nullptr, ResultOutOfMemory); |
| 24 | auto page_buf_guard = SCOPE_GUARD({ KPageBuffer::Free(kernel, page_buf); }); | 24 | auto page_buf_guard = SCOPE_GUARD { |
| 25 | KPageBuffer::Free(kernel, page_buf); | ||
| 26 | }; | ||
| 25 | 27 | ||
| 26 | // Map the address in. | 28 | // Map the address in. |
| 27 | const auto phys_addr = kernel.System().DeviceMemory().GetPhysicalAddr(page_buf); | 29 | const auto phys_addr = kernel.System().DeviceMemory().GetPhysicalAddr(page_buf); |
diff --git a/src/core/hle/kernel/k_transfer_memory.cpp b/src/core/hle/kernel/k_transfer_memory.cpp index cbb1b02bb..09295e8ad 100644 --- a/src/core/hle/kernel/k_transfer_memory.cpp +++ b/src/core/hle/kernel/k_transfer_memory.cpp | |||
| @@ -24,7 +24,9 @@ Result KTransferMemory::Initialize(KProcessAddress addr, std::size_t size, | |||
| 24 | 24 | ||
| 25 | // Construct the page group, guarding to make sure our state is valid on exit. | 25 | // Construct the page group, guarding to make sure our state is valid on exit. |
| 26 | m_page_group.emplace(m_kernel, page_table.GetBlockInfoManager()); | 26 | m_page_group.emplace(m_kernel, page_table.GetBlockInfoManager()); |
| 27 | auto pg_guard = SCOPE_GUARD({ m_page_group.reset(); }); | 27 | auto pg_guard = SCOPE_GUARD { |
| 28 | m_page_group.reset(); | ||
| 29 | }; | ||
| 28 | 30 | ||
| 29 | // Lock the memory. | 31 | // Lock the memory. |
| 30 | R_TRY(page_table.LockForTransferMemory(std::addressof(*m_page_group), addr, size, | 32 | R_TRY(page_table.LockForTransferMemory(std::addressof(*m_page_group), addr, size, |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 4f4b02fac..9e5eaeec4 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -109,7 +109,9 @@ struct KernelCore::Impl { | |||
| 109 | 109 | ||
| 110 | void Shutdown() { | 110 | void Shutdown() { |
| 111 | is_shutting_down.store(true, std::memory_order_relaxed); | 111 | is_shutting_down.store(true, std::memory_order_relaxed); |
| 112 | SCOPE_EXIT({ is_shutting_down.store(false, std::memory_order_relaxed); }); | 112 | SCOPE_EXIT { |
| 113 | is_shutting_down.store(false, std::memory_order_relaxed); | ||
| 114 | }; | ||
| 113 | 115 | ||
| 114 | CloseServices(); | 116 | CloseServices(); |
| 115 | 117 | ||
| @@ -1080,7 +1082,9 @@ std::jthread KernelCore::RunOnHostCoreProcess(std::string&& process_name, | |||
| 1080 | process->Initialize(Svc::CreateProcessParameter{}, GetSystemResourceLimit(), false))); | 1082 | process->Initialize(Svc::CreateProcessParameter{}, GetSystemResourceLimit(), false))); |
| 1081 | 1083 | ||
| 1082 | // Ensure that we don't hold onto any extra references. | 1084 | // Ensure that we don't hold onto any extra references. |
| 1083 | SCOPE_EXIT({ process->Close(); }); | 1085 | SCOPE_EXIT { |
| 1086 | process->Close(); | ||
| 1087 | }; | ||
| 1084 | 1088 | ||
| 1085 | // Register the new process. | 1089 | // Register the new process. |
| 1086 | KProcess::Register(*this, process); | 1090 | KProcess::Register(*this, process); |
| @@ -1108,7 +1112,9 @@ void KernelCore::RunOnGuestCoreProcess(std::string&& process_name, std::function | |||
| 1108 | process->Initialize(Svc::CreateProcessParameter{}, GetSystemResourceLimit(), false))); | 1112 | process->Initialize(Svc::CreateProcessParameter{}, GetSystemResourceLimit(), false))); |
| 1109 | 1113 | ||
| 1110 | // Ensure that we don't hold onto any extra references. | 1114 | // Ensure that we don't hold onto any extra references. |
| 1111 | SCOPE_EXIT({ process->Close(); }); | 1115 | SCOPE_EXIT { |
| 1116 | process->Close(); | ||
| 1117 | }; | ||
| 1112 | 1118 | ||
| 1113 | // Register the new process. | 1119 | // Register the new process. |
| 1114 | KProcess::Register(*this, process); | 1120 | KProcess::Register(*this, process); |
diff --git a/src/core/hle/kernel/svc/svc_code_memory.cpp b/src/core/hle/kernel/svc/svc_code_memory.cpp index bae4cb0cd..7be2802f0 100644 --- a/src/core/hle/kernel/svc/svc_code_memory.cpp +++ b/src/core/hle/kernel/svc/svc_code_memory.cpp | |||
| @@ -45,7 +45,9 @@ Result CreateCodeMemory(Core::System& system, Handle* out, u64 address, uint64_t | |||
| 45 | 45 | ||
| 46 | KCodeMemory* code_mem = KCodeMemory::Create(kernel); | 46 | KCodeMemory* code_mem = KCodeMemory::Create(kernel); |
| 47 | R_UNLESS(code_mem != nullptr, ResultOutOfResource); | 47 | R_UNLESS(code_mem != nullptr, ResultOutOfResource); |
| 48 | SCOPE_EXIT({ code_mem->Close(); }); | 48 | SCOPE_EXIT { |
| 49 | code_mem->Close(); | ||
| 50 | }; | ||
| 49 | 51 | ||
| 50 | // Verify that the region is in range. | 52 | // Verify that the region is in range. |
| 51 | R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().Contains(address, size), | 53 | R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().Contains(address, size), |
diff --git a/src/core/hle/kernel/svc/svc_device_address_space.cpp b/src/core/hle/kernel/svc/svc_device_address_space.cpp index 42add9473..ac828320f 100644 --- a/src/core/hle/kernel/svc/svc_device_address_space.cpp +++ b/src/core/hle/kernel/svc/svc_device_address_space.cpp | |||
| @@ -28,7 +28,9 @@ Result CreateDeviceAddressSpace(Core::System& system, Handle* out, uint64_t das_ | |||
| 28 | // Create the device address space. | 28 | // Create the device address space. |
| 29 | KDeviceAddressSpace* das = KDeviceAddressSpace::Create(system.Kernel()); | 29 | KDeviceAddressSpace* das = KDeviceAddressSpace::Create(system.Kernel()); |
| 30 | R_UNLESS(das != nullptr, ResultOutOfResource); | 30 | R_UNLESS(das != nullptr, ResultOutOfResource); |
| 31 | SCOPE_EXIT({ das->Close(); }); | 31 | SCOPE_EXIT { |
| 32 | das->Close(); | ||
| 33 | }; | ||
| 32 | 34 | ||
| 33 | // Initialize the device address space. | 35 | // Initialize the device address space. |
| 34 | R_TRY(das->Initialize(das_address, das_size)); | 36 | R_TRY(das->Initialize(das_address, das_size)); |
diff --git a/src/core/hle/kernel/svc/svc_event.cpp b/src/core/hle/kernel/svc/svc_event.cpp index 901202e6a..8e4beb396 100644 --- a/src/core/hle/kernel/svc/svc_event.cpp +++ b/src/core/hle/kernel/svc/svc_event.cpp | |||
| @@ -72,10 +72,10 @@ Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) { | |||
| 72 | event_reservation.Commit(); | 72 | event_reservation.Commit(); |
| 73 | 73 | ||
| 74 | // Ensure that we clean up the event (and its only references are handle table) on function end. | 74 | // Ensure that we clean up the event (and its only references are handle table) on function end. |
| 75 | SCOPE_EXIT({ | 75 | SCOPE_EXIT { |
| 76 | event->GetReadableEvent().Close(); | 76 | event->GetReadableEvent().Close(); |
| 77 | event->Close(); | 77 | event->Close(); |
| 78 | }); | 78 | }; |
| 79 | 79 | ||
| 80 | // Register the event. | 80 | // Register the event. |
| 81 | KEvent::Register(kernel, event); | 81 | KEvent::Register(kernel, event); |
diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp index 85cc4f561..b619bd70a 100644 --- a/src/core/hle/kernel/svc/svc_ipc.cpp +++ b/src/core/hle/kernel/svc/svc_ipc.cpp | |||
| @@ -129,11 +129,11 @@ Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t mes | |||
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | // Ensure handles are closed when we're done. | 131 | // Ensure handles are closed when we're done. |
| 132 | SCOPE_EXIT({ | 132 | SCOPE_EXIT { |
| 133 | for (auto i = 0; i < num_handles; ++i) { | 133 | for (auto i = 0; i < num_handles; ++i) { |
| 134 | objs[i]->Close(); | 134 | objs[i]->Close(); |
| 135 | } | 135 | } |
| 136 | }); | 136 | }; |
| 137 | 137 | ||
| 138 | R_RETURN(ReplyAndReceiveImpl(kernel, out_index, message, buffer_size, message_paddr, objs, | 138 | R_RETURN(ReplyAndReceiveImpl(kernel, out_index, message, buffer_size, message_paddr, objs, |
| 139 | num_handles, reply_target, timeout_ns)); | 139 | num_handles, reply_target, timeout_ns)); |
| @@ -208,10 +208,10 @@ Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_ha | |||
| 208 | event_reservation.Commit(); | 208 | event_reservation.Commit(); |
| 209 | 209 | ||
| 210 | // At end of scope, kill the standing references to the sub events. | 210 | // At end of scope, kill the standing references to the sub events. |
| 211 | SCOPE_EXIT({ | 211 | SCOPE_EXIT { |
| 212 | event->GetReadableEvent().Close(); | 212 | event->GetReadableEvent().Close(); |
| 213 | event->Close(); | 213 | event->Close(); |
| 214 | }); | 214 | }; |
| 215 | 215 | ||
| 216 | // Register the event. | 216 | // Register the event. |
| 217 | KEvent::Register(system.Kernel(), event); | 217 | KEvent::Register(system.Kernel(), event); |
diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp index 737749f7d..9a22dadaf 100644 --- a/src/core/hle/kernel/svc/svc_port.cpp +++ b/src/core/hle/kernel/svc/svc_port.cpp | |||
| @@ -68,10 +68,10 @@ Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client, | |||
| 68 | port->Initialize(max_sessions, is_light, name); | 68 | port->Initialize(max_sessions, is_light, name); |
| 69 | 69 | ||
| 70 | // Ensure that we clean up the port (and its only references are handle table) on function end. | 70 | // Ensure that we clean up the port (and its only references are handle table) on function end. |
| 71 | SCOPE_EXIT({ | 71 | SCOPE_EXIT { |
| 72 | port->GetServerPort().Close(); | 72 | port->GetServerPort().Close(); |
| 73 | port->GetClientPort().Close(); | 73 | port->GetClientPort().Close(); |
| 74 | }); | 74 | }; |
| 75 | 75 | ||
| 76 | // Register the port. | 76 | // Register the port. |
| 77 | KPort::Register(kernel, port); | 77 | KPort::Register(kernel, port); |
| @@ -150,10 +150,10 @@ Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t | |||
| 150 | KPort::Register(system.Kernel(), port); | 150 | KPort::Register(system.Kernel(), port); |
| 151 | 151 | ||
| 152 | // Ensure that our only reference to the port is in the handle table when we're done. | 152 | // Ensure that our only reference to the port is in the handle table when we're done. |
| 153 | SCOPE_EXIT({ | 153 | SCOPE_EXIT { |
| 154 | port->GetClientPort().Close(); | 154 | port->GetClientPort().Close(); |
| 155 | port->GetServerPort().Close(); | 155 | port->GetServerPort().Close(); |
| 156 | }); | 156 | }; |
| 157 | 157 | ||
| 158 | // Register the handle in the table. | 158 | // Register the handle in the table. |
| 159 | R_TRY(handle_table.Add(out_server_handle, std::addressof(port->GetServerPort()))); | 159 | R_TRY(handle_table.Add(out_server_handle, std::addressof(port->GetServerPort()))); |
diff --git a/src/core/hle/kernel/svc/svc_resource_limit.cpp b/src/core/hle/kernel/svc/svc_resource_limit.cpp index c8e820b6a..6f3972482 100644 --- a/src/core/hle/kernel/svc/svc_resource_limit.cpp +++ b/src/core/hle/kernel/svc/svc_resource_limit.cpp | |||
| @@ -18,7 +18,9 @@ Result CreateResourceLimit(Core::System& system, Handle* out_handle) { | |||
| 18 | R_UNLESS(resource_limit != nullptr, ResultOutOfResource); | 18 | R_UNLESS(resource_limit != nullptr, ResultOutOfResource); |
| 19 | 19 | ||
| 20 | // Ensure we don't leak a reference to the limit. | 20 | // Ensure we don't leak a reference to the limit. |
| 21 | SCOPE_EXIT({ resource_limit->Close(); }); | 21 | SCOPE_EXIT { |
| 22 | resource_limit->Close(); | ||
| 23 | }; | ||
| 22 | 24 | ||
| 23 | // Initialize the resource limit. | 25 | // Initialize the resource limit. |
| 24 | resource_limit->Initialize(); | 26 | resource_limit->Initialize(); |
diff --git a/src/core/hle/kernel/svc/svc_session.cpp b/src/core/hle/kernel/svc/svc_session.cpp index 2f5905f32..b034d21d1 100644 --- a/src/core/hle/kernel/svc/svc_session.cpp +++ b/src/core/hle/kernel/svc/svc_session.cpp | |||
| @@ -69,10 +69,10 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien | |||
| 69 | 69 | ||
| 70 | // Ensure that we clean up the session (and its only references are handle table) on function | 70 | // Ensure that we clean up the session (and its only references are handle table) on function |
| 71 | // end. | 71 | // end. |
| 72 | SCOPE_EXIT({ | 72 | SCOPE_EXIT { |
| 73 | session->GetClientSession().Close(); | 73 | session->GetClientSession().Close(); |
| 74 | session->GetServerSession().Close(); | 74 | session->GetServerSession().Close(); |
| 75 | }); | 75 | }; |
| 76 | 76 | ||
| 77 | // Register the session. | 77 | // Register the session. |
| 78 | T::Register(system.Kernel(), session); | 78 | T::Register(system.Kernel(), session); |
diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp index 6c79cfd8d..fb03908d7 100644 --- a/src/core/hle/kernel/svc/svc_synchronization.cpp +++ b/src/core/hle/kernel/svc/svc_synchronization.cpp | |||
| @@ -78,11 +78,11 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha | |||
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | // Ensure handles are closed when we're done. | 80 | // Ensure handles are closed when we're done. |
| 81 | SCOPE_EXIT({ | 81 | SCOPE_EXIT { |
| 82 | for (auto i = 0; i < num_handles; ++i) { | 82 | for (auto i = 0; i < num_handles; ++i) { |
| 83 | objs[i]->Close(); | 83 | objs[i]->Close(); |
| 84 | } | 84 | } |
| 85 | }); | 85 | }; |
| 86 | 86 | ||
| 87 | // Convert the timeout from nanoseconds to ticks. | 87 | // Convert the timeout from nanoseconds to ticks. |
| 88 | s64 timeout; | 88 | s64 timeout; |
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index 7681afa33..7517bb9d3 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp | |||
| @@ -51,7 +51,9 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u | |||
| 51 | // Create the thread. | 51 | // Create the thread. |
| 52 | KThread* thread = KThread::Create(kernel); | 52 | KThread* thread = KThread::Create(kernel); |
| 53 | R_UNLESS(thread != nullptr, ResultOutOfResource) | 53 | R_UNLESS(thread != nullptr, ResultOutOfResource) |
| 54 | SCOPE_EXIT({ thread->Close(); }); | 54 | SCOPE_EXIT { |
| 55 | thread->Close(); | ||
| 56 | }; | ||
| 55 | 57 | ||
| 56 | // Initialize the thread. | 58 | // Initialize the thread. |
| 57 | { | 59 | { |
diff --git a/src/core/hle/kernel/svc/svc_transfer_memory.cpp b/src/core/hle/kernel/svc/svc_transfer_memory.cpp index 671bca23f..2ea0d4421 100644 --- a/src/core/hle/kernel/svc/svc_transfer_memory.cpp +++ b/src/core/hle/kernel/svc/svc_transfer_memory.cpp | |||
| @@ -52,7 +52,9 @@ Result CreateTransferMemory(Core::System& system, Handle* out, u64 address, u64 | |||
| 52 | R_UNLESS(trmem != nullptr, ResultOutOfResource); | 52 | R_UNLESS(trmem != nullptr, ResultOutOfResource); |
| 53 | 53 | ||
| 54 | // Ensure the only reference is in the handle table when we're done. | 54 | // Ensure the only reference is in the handle table when we're done. |
| 55 | SCOPE_EXIT({ trmem->Close(); }); | 55 | SCOPE_EXIT { |
| 56 | trmem->Close(); | ||
| 57 | }; | ||
| 56 | 58 | ||
| 57 | // Ensure that the region is in range. | 59 | // Ensure that the region is in range. |
| 58 | R_UNLESS(process.GetPageTable().Contains(address, size), ResultInvalidCurrentMemory); | 60 | R_UNLESS(process.GetPageTable().Contains(address, size), ResultInvalidCurrentMemory); |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 9dc710ba9..8c4e14f08 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -8,13 +8,13 @@ | |||
| 8 | 8 | ||
| 9 | namespace Service::AM { | 9 | namespace Service::AM { |
| 10 | 10 | ||
| 11 | void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { | 11 | void LoopProcess(Core::System& system) { |
| 12 | auto server_manager = std::make_unique<ServerManager>(system); | 12 | auto server_manager = std::make_unique<ServerManager>(system); |
| 13 | 13 | ||
| 14 | server_manager->RegisterNamedService( | 14 | server_manager->RegisterNamedService("appletAE", |
| 15 | "appletAE", std::make_shared<IAllSystemAppletProxiesService>(system, nvnflinger)); | 15 | std::make_shared<IAllSystemAppletProxiesService>(system)); |
| 16 | server_manager->RegisterNamedService( | 16 | server_manager->RegisterNamedService("appletOE", |
| 17 | "appletOE", std::make_shared<IApplicationProxyService>(system, nvnflinger)); | 17 | std::make_shared<IApplicationProxyService>(system)); |
| 18 | ServerManager::RunServer(std::move(server_manager)); | 18 | ServerManager::RunServer(std::move(server_manager)); |
| 19 | } | 19 | } |
| 20 | 20 | ||
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 4a2d797bd..1afe253ae 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h | |||
| @@ -7,12 +7,8 @@ namespace Core { | |||
| 7 | class System; | 7 | class System; |
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | namespace Service::Nvnflinger { | ||
| 11 | class Nvnflinger; | ||
| 12 | } | ||
| 13 | |||
| 14 | namespace Service::AM { | 10 | namespace Service::AM { |
| 15 | 11 | ||
| 16 | void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system); | 12 | void LoopProcess(Core::System& system); |
| 17 | 13 | ||
| 18 | } // namespace Service::AM | 14 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applet.h b/src/core/hle/service/am/applet.h index 4f34d4811..ad602153e 100644 --- a/src/core/hle/service/am/applet.h +++ b/src/core/hle/service/am/applet.h | |||
| @@ -14,10 +14,9 @@ | |||
| 14 | 14 | ||
| 15 | #include "core/hle/service/am/am_types.h" | 15 | #include "core/hle/service/am/am_types.h" |
| 16 | #include "core/hle/service/am/applet_message_queue.h" | 16 | #include "core/hle/service/am/applet_message_queue.h" |
| 17 | #include "core/hle/service/am/display_layer_manager.h" | ||
| 17 | #include "core/hle/service/am/hid_registration.h" | 18 | #include "core/hle/service/am/hid_registration.h" |
| 18 | #include "core/hle/service/am/managed_layer_holder.h" | ||
| 19 | #include "core/hle/service/am/process.h" | 19 | #include "core/hle/service/am/process.h" |
| 20 | #include "core/hle/service/am/system_buffer_manager.h" | ||
| 21 | 20 | ||
| 22 | namespace Service::AM { | 21 | namespace Service::AM { |
| 23 | 22 | ||
| @@ -54,8 +53,7 @@ struct Applet { | |||
| 54 | HidRegistration hid_registration; | 53 | HidRegistration hid_registration; |
| 55 | 54 | ||
| 56 | // vi state | 55 | // vi state |
| 57 | SystemBufferManager system_buffer_manager{}; | 56 | DisplayLayerManager display_layer_manager{}; |
| 58 | ManagedLayerHolder managed_layer_holder{}; | ||
| 59 | 57 | ||
| 60 | // Applet common functions | 58 | // Applet common functions |
| 61 | Result terminate_result{}; | 59 | Result terminate_result{}; |
diff --git a/src/core/hle/service/am/applet_data_broker.cpp b/src/core/hle/service/am/applet_data_broker.cpp index 4d58c4db5..9057244a9 100644 --- a/src/core/hle/service/am/applet_data_broker.cpp +++ b/src/core/hle/service/am/applet_data_broker.cpp | |||
| @@ -24,11 +24,11 @@ void AppletStorageChannel::Push(std::shared_ptr<IStorage> storage) { | |||
| 24 | Result AppletStorageChannel::Pop(std::shared_ptr<IStorage>* out_storage) { | 24 | Result AppletStorageChannel::Pop(std::shared_ptr<IStorage>* out_storage) { |
| 25 | std::scoped_lock lk{m_lock}; | 25 | std::scoped_lock lk{m_lock}; |
| 26 | 26 | ||
| 27 | SCOPE_EXIT({ | 27 | SCOPE_EXIT { |
| 28 | if (m_data.empty()) { | 28 | if (m_data.empty()) { |
| 29 | m_event.Clear(); | 29 | m_event.Clear(); |
| 30 | } | 30 | } |
| 31 | }); | 31 | }; |
| 32 | 32 | ||
| 33 | R_UNLESS(!m_data.empty(), AM::ResultNoDataInChannel); | 33 | R_UNLESS(!m_data.empty(), AM::ResultNoDataInChannel); |
| 34 | 34 | ||
diff --git a/src/core/hle/service/am/display_layer_manager.cpp b/src/core/hle/service/am/display_layer_manager.cpp new file mode 100644 index 000000000..85ff6fb88 --- /dev/null +++ b/src/core/hle/service/am/display_layer_manager.cpp | |||
| @@ -0,0 +1,151 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/core.h" | ||
| 5 | #include "core/hle/service/am/display_layer_manager.h" | ||
| 6 | #include "core/hle/service/sm/sm.h" | ||
| 7 | #include "core/hle/service/vi/application_display_service.h" | ||
| 8 | #include "core/hle/service/vi/container.h" | ||
| 9 | #include "core/hle/service/vi/manager_display_service.h" | ||
| 10 | #include "core/hle/service/vi/manager_root_service.h" | ||
| 11 | #include "core/hle/service/vi/shared_buffer_manager.h" | ||
| 12 | #include "core/hle/service/vi/vi_results.h" | ||
| 13 | #include "core/hle/service/vi/vi_types.h" | ||
| 14 | |||
| 15 | namespace Service::AM { | ||
| 16 | |||
| 17 | DisplayLayerManager::DisplayLayerManager() = default; | ||
| 18 | DisplayLayerManager::~DisplayLayerManager() { | ||
| 19 | this->Finalize(); | ||
| 20 | } | ||
| 21 | |||
| 22 | void DisplayLayerManager::Initialize(Core::System& system, Kernel::KProcess* process, | ||
| 23 | AppletId applet_id, LibraryAppletMode mode) { | ||
| 24 | R_ASSERT(system.ServiceManager() | ||
| 25 | .GetService<VI::IManagerRootService>("vi:m", true) | ||
| 26 | ->GetDisplayService(&m_display_service, VI::Policy::Compositor)); | ||
| 27 | R_ASSERT(m_display_service->GetManagerDisplayService(&m_manager_display_service)); | ||
| 28 | |||
| 29 | m_process = process; | ||
| 30 | m_system_shared_buffer_id = 0; | ||
| 31 | m_system_shared_layer_id = 0; | ||
| 32 | m_applet_id = applet_id; | ||
| 33 | m_buffer_sharing_enabled = false; | ||
| 34 | m_blending_enabled = mode == LibraryAppletMode::PartialForeground || | ||
| 35 | mode == LibraryAppletMode::PartialForegroundIndirectDisplay; | ||
| 36 | } | ||
| 37 | |||
| 38 | void DisplayLayerManager::Finalize() { | ||
| 39 | if (!m_manager_display_service) { | ||
| 40 | return; | ||
| 41 | } | ||
| 42 | |||
| 43 | // Clean up managed layers. | ||
| 44 | for (const auto& layer : m_managed_display_layers) { | ||
| 45 | m_manager_display_service->DestroyManagedLayer(layer); | ||
| 46 | } | ||
| 47 | |||
| 48 | for (const auto& layer : m_managed_display_recording_layers) { | ||
| 49 | m_manager_display_service->DestroyManagedLayer(layer); | ||
| 50 | } | ||
| 51 | |||
| 52 | // Clean up shared layers. | ||
| 53 | if (m_buffer_sharing_enabled) { | ||
| 54 | m_manager_display_service->DestroySharedLayerSession(m_process); | ||
| 55 | } | ||
| 56 | |||
| 57 | m_manager_display_service = nullptr; | ||
| 58 | m_display_service = nullptr; | ||
| 59 | } | ||
| 60 | |||
| 61 | Result DisplayLayerManager::CreateManagedDisplayLayer(u64* out_layer_id) { | ||
| 62 | R_UNLESS(m_manager_display_service != nullptr, VI::ResultOperationFailed); | ||
| 63 | |||
| 64 | // TODO(Subv): Find out how AM determines the display to use, for now just | ||
| 65 | // create the layer in the Default display. | ||
| 66 | u64 display_id; | ||
| 67 | R_TRY(m_display_service->OpenDisplay(&display_id, VI::DisplayName{"Default"})); | ||
| 68 | R_TRY(m_manager_display_service->CreateManagedLayer( | ||
| 69 | out_layer_id, 0, display_id, Service::AppletResourceUserId{m_process->GetProcessId()})); | ||
| 70 | |||
| 71 | m_manager_display_service->SetLayerVisibility(m_visible, *out_layer_id); | ||
| 72 | m_managed_display_layers.emplace(*out_layer_id); | ||
| 73 | |||
| 74 | R_SUCCEED(); | ||
| 75 | } | ||
| 76 | |||
| 77 | Result DisplayLayerManager::CreateManagedDisplaySeparableLayer(u64* out_layer_id, | ||
| 78 | u64* out_recording_layer_id) { | ||
| 79 | R_UNLESS(m_manager_display_service != nullptr, VI::ResultOperationFailed); | ||
| 80 | |||
| 81 | // TODO(Subv): Find out how AM determines the display to use, for now just | ||
| 82 | // create the layer in the Default display. | ||
| 83 | // This calls nn::vi::CreateRecordingLayer() which creates another layer. | ||
| 84 | // Currently we do not support more than 1 layer per display, output 1 layer id for now. | ||
| 85 | // Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse | ||
| 86 | // side effects. | ||
| 87 | *out_recording_layer_id = 0; | ||
| 88 | R_RETURN(this->CreateManagedDisplayLayer(out_layer_id)); | ||
| 89 | } | ||
| 90 | |||
| 91 | Result DisplayLayerManager::IsSystemBufferSharingEnabled() { | ||
| 92 | // Succeed if already enabled. | ||
| 93 | R_SUCCEED_IF(m_buffer_sharing_enabled); | ||
| 94 | |||
| 95 | // Ensure we can access shared layers. | ||
| 96 | R_UNLESS(m_manager_display_service != nullptr, VI::ResultOperationFailed); | ||
| 97 | R_UNLESS(m_applet_id != AppletId::Application, VI::ResultPermissionDenied); | ||
| 98 | |||
| 99 | // Create the shared layer. | ||
| 100 | u64 display_id; | ||
| 101 | R_TRY(m_display_service->OpenDisplay(&display_id, VI::DisplayName{"Default"})); | ||
| 102 | R_TRY(m_manager_display_service->CreateSharedLayerSession(m_process, &m_system_shared_buffer_id, | ||
| 103 | &m_system_shared_layer_id, display_id, | ||
| 104 | m_blending_enabled)); | ||
| 105 | |||
| 106 | // We succeeded, so set up remaining state. | ||
| 107 | m_buffer_sharing_enabled = true; | ||
| 108 | m_manager_display_service->SetLayerVisibility(m_visible, m_system_shared_layer_id); | ||
| 109 | R_SUCCEED(); | ||
| 110 | } | ||
| 111 | |||
| 112 | Result DisplayLayerManager::GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id, | ||
| 113 | u64* out_system_shared_layer_id) { | ||
| 114 | R_TRY(this->IsSystemBufferSharingEnabled()); | ||
| 115 | |||
| 116 | *out_system_shared_buffer_id = m_system_shared_buffer_id; | ||
| 117 | *out_system_shared_layer_id = m_system_shared_layer_id; | ||
| 118 | |||
| 119 | R_SUCCEED(); | ||
| 120 | } | ||
| 121 | |||
| 122 | void DisplayLayerManager::SetWindowVisibility(bool visible) { | ||
| 123 | if (m_visible == visible) { | ||
| 124 | return; | ||
| 125 | } | ||
| 126 | |||
| 127 | m_visible = visible; | ||
| 128 | |||
| 129 | if (m_manager_display_service) { | ||
| 130 | if (m_system_shared_layer_id) { | ||
| 131 | m_manager_display_service->SetLayerVisibility(m_visible, m_system_shared_layer_id); | ||
| 132 | } | ||
| 133 | |||
| 134 | for (const auto layer_id : m_managed_display_layers) { | ||
| 135 | m_manager_display_service->SetLayerVisibility(m_visible, layer_id); | ||
| 136 | } | ||
| 137 | } | ||
| 138 | } | ||
| 139 | |||
| 140 | bool DisplayLayerManager::GetWindowVisibility() const { | ||
| 141 | return m_visible; | ||
| 142 | } | ||
| 143 | |||
| 144 | Result DisplayLayerManager::WriteAppletCaptureBuffer(bool* out_was_written, | ||
| 145 | s32* out_fbshare_layer_index) { | ||
| 146 | R_UNLESS(m_buffer_sharing_enabled, VI::ResultPermissionDenied); | ||
| 147 | R_RETURN(m_display_service->GetContainer()->GetSharedBufferManager()->WriteAppletCaptureBuffer( | ||
| 148 | out_was_written, out_fbshare_layer_index)); | ||
| 149 | } | ||
| 150 | |||
| 151 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/display_layer_manager.h b/src/core/hle/service/am/display_layer_manager.h new file mode 100644 index 000000000..a66509c04 --- /dev/null +++ b/src/core/hle/service/am/display_layer_manager.h | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <set> | ||
| 7 | |||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "core/hle/result.h" | ||
| 10 | #include "core/hle/service/am/am_types.h" | ||
| 11 | |||
| 12 | namespace Core { | ||
| 13 | class System; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace Kernel { | ||
| 17 | class KProcess; | ||
| 18 | } | ||
| 19 | |||
| 20 | namespace Service::VI { | ||
| 21 | class IApplicationDisplayService; | ||
| 22 | class IManagerDisplayService; | ||
| 23 | } // namespace Service::VI | ||
| 24 | |||
| 25 | namespace Service::AM { | ||
| 26 | |||
| 27 | class DisplayLayerManager { | ||
| 28 | public: | ||
| 29 | explicit DisplayLayerManager(); | ||
| 30 | ~DisplayLayerManager(); | ||
| 31 | |||
| 32 | void Initialize(Core::System& system, Kernel::KProcess* process, AppletId applet_id, | ||
| 33 | LibraryAppletMode mode); | ||
| 34 | void Finalize(); | ||
| 35 | |||
| 36 | Result CreateManagedDisplayLayer(u64* out_layer_id); | ||
| 37 | Result CreateManagedDisplaySeparableLayer(u64* out_layer_id, u64* out_recording_layer_id); | ||
| 38 | |||
| 39 | Result IsSystemBufferSharingEnabled(); | ||
| 40 | Result GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id, | ||
| 41 | u64* out_system_shared_layer_id); | ||
| 42 | |||
| 43 | void SetWindowVisibility(bool visible); | ||
| 44 | bool GetWindowVisibility() const; | ||
| 45 | |||
| 46 | Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index); | ||
| 47 | |||
| 48 | private: | ||
| 49 | Kernel::KProcess* m_process{}; | ||
| 50 | std::shared_ptr<VI::IApplicationDisplayService> m_display_service{}; | ||
| 51 | std::shared_ptr<VI::IManagerDisplayService> m_manager_display_service{}; | ||
| 52 | std::set<u64> m_managed_display_layers{}; | ||
| 53 | std::set<u64> m_managed_display_recording_layers{}; | ||
| 54 | u64 m_system_shared_buffer_id{}; | ||
| 55 | u64 m_system_shared_layer_id{}; | ||
| 56 | AppletId m_applet_id{}; | ||
| 57 | bool m_buffer_sharing_enabled{}; | ||
| 58 | bool m_blending_enabled{}; | ||
| 59 | bool m_visible{true}; | ||
| 60 | }; | ||
| 61 | |||
| 62 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/frontend/applet_web_browser.cpp b/src/core/hle/service/am/frontend/applet_web_browser.cpp index bb60260b4..835c20c4e 100644 --- a/src/core/hle/service/am/frontend/applet_web_browser.cpp +++ b/src/core/hle/service/am/frontend/applet_web_browser.cpp | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | #include "core/hle/service/am/frontend/applet_web_browser.h" | 22 | #include "core/hle/service/am/frontend/applet_web_browser.h" |
| 23 | #include "core/hle/service/am/service/storage.h" | 23 | #include "core/hle/service/am/service/storage.h" |
| 24 | #include "core/hle/service/filesystem/filesystem.h" | 24 | #include "core/hle/service/filesystem/filesystem.h" |
| 25 | #include "core/hle/service/ns/iplatform_service_manager.h" | 25 | #include "core/hle/service/ns/platform_service_manager.h" |
| 26 | #include "core/loader/loader.h" | 26 | #include "core/loader/loader.h" |
| 27 | 27 | ||
| 28 | namespace Service::AM::Frontend { | 28 | namespace Service::AM::Frontend { |
diff --git a/src/core/hle/service/am/library_applet_storage.cpp b/src/core/hle/service/am/library_applet_storage.cpp index 46e6c0111..0412c215d 100644 --- a/src/core/hle/service/am/library_applet_storage.cpp +++ b/src/core/hle/service/am/library_applet_storage.cpp | |||
| @@ -70,7 +70,7 @@ public: | |||
| 70 | Result Read(s64 offset, void* buffer, size_t size) override { | 70 | Result Read(s64 offset, void* buffer, size_t size) override { |
| 71 | R_TRY(ValidateOffset(offset, size, m_size)); | 71 | R_TRY(ValidateOffset(offset, size, m_size)); |
| 72 | 72 | ||
| 73 | m_memory.ReadBlock(m_trmem->GetSourceAddress(), buffer, size); | 73 | m_memory.ReadBlock(m_trmem->GetSourceAddress() + offset, buffer, size); |
| 74 | 74 | ||
| 75 | R_SUCCEED(); | 75 | R_SUCCEED(); |
| 76 | } | 76 | } |
| @@ -79,7 +79,7 @@ public: | |||
| 79 | R_UNLESS(m_is_writable, ResultUnknown); | 79 | R_UNLESS(m_is_writable, ResultUnknown); |
| 80 | R_TRY(ValidateOffset(offset, size, m_size)); | 80 | R_TRY(ValidateOffset(offset, size, m_size)); |
| 81 | 81 | ||
| 82 | m_memory.WriteBlock(m_trmem->GetSourceAddress(), buffer, size); | 82 | m_memory.WriteBlock(m_trmem->GetSourceAddress() + offset, buffer, size); |
| 83 | 83 | ||
| 84 | R_SUCCEED(); | 84 | R_SUCCEED(); |
| 85 | } | 85 | } |
diff --git a/src/core/hle/service/am/managed_layer_holder.cpp b/src/core/hle/service/am/managed_layer_holder.cpp deleted file mode 100644 index 61eb8641a..000000000 --- a/src/core/hle/service/am/managed_layer_holder.cpp +++ /dev/null | |||
| @@ -1,59 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/managed_layer_holder.h" | ||
| 5 | #include "core/hle/service/nvnflinger/nvnflinger.h" | ||
| 6 | |||
| 7 | namespace Service::AM { | ||
| 8 | |||
| 9 | ManagedLayerHolder::ManagedLayerHolder() = default; | ||
| 10 | ManagedLayerHolder::~ManagedLayerHolder() { | ||
| 11 | if (!m_nvnflinger) { | ||
| 12 | return; | ||
| 13 | } | ||
| 14 | |||
| 15 | for (const auto& layer : m_managed_display_layers) { | ||
| 16 | m_nvnflinger->DestroyLayer(layer); | ||
| 17 | } | ||
| 18 | |||
| 19 | for (const auto& layer : m_managed_display_recording_layers) { | ||
| 20 | m_nvnflinger->DestroyLayer(layer); | ||
| 21 | } | ||
| 22 | |||
| 23 | m_nvnflinger = nullptr; | ||
| 24 | } | ||
| 25 | |||
| 26 | void ManagedLayerHolder::Initialize(Nvnflinger::Nvnflinger* nvnflinger) { | ||
| 27 | m_nvnflinger = nvnflinger; | ||
| 28 | } | ||
| 29 | |||
| 30 | void ManagedLayerHolder::CreateManagedDisplayLayer(u64* out_layer) { | ||
| 31 | // TODO(Subv): Find out how AM determines the display to use, for now just | ||
| 32 | // create the layer in the Default display. | ||
| 33 | const auto display_id = m_nvnflinger->OpenDisplay("Default"); | ||
| 34 | const auto layer_id = m_nvnflinger->CreateLayer(*display_id); | ||
| 35 | |||
| 36 | m_managed_display_layers.emplace(*layer_id); | ||
| 37 | |||
| 38 | *out_layer = *layer_id; | ||
| 39 | } | ||
| 40 | |||
| 41 | void ManagedLayerHolder::CreateManagedDisplaySeparableLayer(u64* out_layer, | ||
| 42 | u64* out_recording_layer) { | ||
| 43 | // TODO(Subv): Find out how AM determines the display to use, for now just | ||
| 44 | // create the layer in the Default display. | ||
| 45 | // This calls nn::vi::CreateRecordingLayer() which creates another layer. | ||
| 46 | // Currently we do not support more than 1 layer per display, output 1 layer id for now. | ||
| 47 | // Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse | ||
| 48 | // side effects. | ||
| 49 | // TODO: Support multiple layers | ||
| 50 | const auto display_id = m_nvnflinger->OpenDisplay("Default"); | ||
| 51 | const auto layer_id = m_nvnflinger->CreateLayer(*display_id); | ||
| 52 | |||
| 53 | m_managed_display_layers.emplace(*layer_id); | ||
| 54 | |||
| 55 | *out_layer = *layer_id; | ||
| 56 | *out_recording_layer = 0; | ||
| 57 | } | ||
| 58 | |||
| 59 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/managed_layer_holder.h b/src/core/hle/service/am/managed_layer_holder.h deleted file mode 100644 index f7fe03f24..000000000 --- a/src/core/hle/service/am/managed_layer_holder.h +++ /dev/null | |||
| @@ -1,32 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <set> | ||
| 7 | |||
| 8 | #include "common/common_funcs.h" | ||
| 9 | #include "common/common_types.h" | ||
| 10 | |||
| 11 | namespace Service::Nvnflinger { | ||
| 12 | class Nvnflinger; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace Service::AM { | ||
| 16 | |||
| 17 | class ManagedLayerHolder { | ||
| 18 | public: | ||
| 19 | ManagedLayerHolder(); | ||
| 20 | ~ManagedLayerHolder(); | ||
| 21 | |||
| 22 | void Initialize(Nvnflinger::Nvnflinger* nvnflinger); | ||
| 23 | void CreateManagedDisplayLayer(u64* out_layer); | ||
| 24 | void CreateManagedDisplaySeparableLayer(u64* out_layer, u64* out_recording_layer); | ||
| 25 | |||
| 26 | private: | ||
| 27 | Nvnflinger::Nvnflinger* m_nvnflinger{}; | ||
| 28 | std::set<u64> m_managed_display_layers{}; | ||
| 29 | std::set<u64> m_managed_display_recording_layers{}; | ||
| 30 | }; | ||
| 31 | |||
| 32 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/process.cpp b/src/core/hle/service/am/process.cpp index 992c50713..388d2045c 100644 --- a/src/core/hle/service/am/process.cpp +++ b/src/core/hle/service/am/process.cpp | |||
| @@ -68,7 +68,9 @@ bool Process::Initialize(u64 program_id, u8 minimum_key_generation, u8 maximum_k | |||
| 68 | Kernel::KProcess::Register(m_system.Kernel(), process); | 68 | Kernel::KProcess::Register(m_system.Kernel(), process); |
| 69 | 69 | ||
| 70 | // On exit, ensure we free the additional reference to the process. | 70 | // On exit, ensure we free the additional reference to the process. |
| 71 | SCOPE_EXIT({ process->Close(); }); | 71 | SCOPE_EXIT { |
| 72 | process->Close(); | ||
| 73 | }; | ||
| 72 | 74 | ||
| 73 | // Insert process modules into memory. | 75 | // Insert process modules into memory. |
| 74 | const auto [load_result, load_parameters] = app_loader->Load(*process, m_system); | 76 | const auto [load_result, load_parameters] = app_loader->Load(*process, m_system); |
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp index eebd90ba2..21747783a 100644 --- a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp | |||
| @@ -10,9 +10,8 @@ | |||
| 10 | 10 | ||
| 11 | namespace Service::AM { | 11 | namespace Service::AM { |
| 12 | 12 | ||
| 13 | IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_, | 13 | IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_) |
| 14 | Nvnflinger::Nvnflinger& nvnflinger) | 14 | : ServiceFramework{system_, "appletAE"} { |
| 15 | : ServiceFramework{system_, "appletAE"}, m_nvnflinger{nvnflinger} { | ||
| 16 | // clang-format off | 15 | // clang-format off |
| 17 | static const FunctionInfo functions[] = { | 16 | static const FunctionInfo functions[] = { |
| 18 | {100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"}, | 17 | {100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"}, |
| @@ -37,8 +36,8 @@ Result IAllSystemAppletProxiesService::OpenSystemAppletProxy( | |||
| 37 | LOG_DEBUG(Service_AM, "called"); | 36 | LOG_DEBUG(Service_AM, "called"); |
| 38 | 37 | ||
| 39 | if (const auto applet = this->GetAppletFromProcessId(pid); applet) { | 38 | if (const auto applet = this->GetAppletFromProcessId(pid); applet) { |
| 40 | *out_system_applet_proxy = std::make_shared<ISystemAppletProxy>( | 39 | *out_system_applet_proxy = |
| 41 | system, applet, process_handle.Get(), m_nvnflinger); | 40 | std::make_shared<ISystemAppletProxy>(system, applet, process_handle.Get()); |
| 42 | R_SUCCEED(); | 41 | R_SUCCEED(); |
| 43 | } else { | 42 | } else { |
| 44 | UNIMPLEMENTED(); | 43 | UNIMPLEMENTED(); |
| @@ -53,8 +52,8 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy( | |||
| 53 | LOG_DEBUG(Service_AM, "called"); | 52 | LOG_DEBUG(Service_AM, "called"); |
| 54 | 53 | ||
| 55 | if (const auto applet = this->GetAppletFromProcessId(pid); applet) { | 54 | if (const auto applet = this->GetAppletFromProcessId(pid); applet) { |
| 56 | *out_library_applet_proxy = std::make_shared<ILibraryAppletProxy>( | 55 | *out_library_applet_proxy = |
| 57 | system, applet, process_handle.Get(), m_nvnflinger); | 56 | std::make_shared<ILibraryAppletProxy>(system, applet, process_handle.Get()); |
| 58 | R_SUCCEED(); | 57 | R_SUCCEED(); |
| 59 | } else { | 58 | } else { |
| 60 | UNIMPLEMENTED(); | 59 | UNIMPLEMENTED(); |
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.h b/src/core/hle/service/am/service/all_system_applet_proxies_service.h index 38b1ca2ea..0e2dcb86d 100644 --- a/src/core/hle/service/am/service/all_system_applet_proxies_service.h +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.h | |||
| @@ -8,10 +8,6 @@ | |||
| 8 | 8 | ||
| 9 | namespace Service { | 9 | namespace Service { |
| 10 | 10 | ||
| 11 | namespace Nvnflinger { | ||
| 12 | class Nvnflinger; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace AM { | 11 | namespace AM { |
| 16 | 12 | ||
| 17 | struct Applet; | 13 | struct Applet; |
| @@ -22,8 +18,7 @@ class ISystemAppletProxy; | |||
| 22 | class IAllSystemAppletProxiesService final | 18 | class IAllSystemAppletProxiesService final |
| 23 | : public ServiceFramework<IAllSystemAppletProxiesService> { | 19 | : public ServiceFramework<IAllSystemAppletProxiesService> { |
| 24 | public: | 20 | public: |
| 25 | explicit IAllSystemAppletProxiesService(Core::System& system_, | 21 | explicit IAllSystemAppletProxiesService(Core::System& system_); |
| 26 | Nvnflinger::Nvnflinger& nvnflinger); | ||
| 27 | ~IAllSystemAppletProxiesService() override; | 22 | ~IAllSystemAppletProxiesService() override; |
| 28 | 23 | ||
| 29 | private: | 24 | private: |
| @@ -40,7 +35,6 @@ private: | |||
| 40 | 35 | ||
| 41 | private: | 36 | private: |
| 42 | std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); | 37 | std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); |
| 43 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
| 44 | }; | 38 | }; |
| 45 | 39 | ||
| 46 | } // namespace AM | 40 | } // namespace AM |
diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp index 63dd12a47..cb53b07e0 100644 --- a/src/core/hle/service/am/service/application_functions.cpp +++ b/src/core/hle/service/am/service/application_functions.cpp | |||
| @@ -16,7 +16,8 @@ | |||
| 16 | #include "core/hle/service/filesystem/filesystem.h" | 16 | #include "core/hle/service/filesystem/filesystem.h" |
| 17 | #include "core/hle/service/filesystem/save_data_controller.h" | 17 | #include "core/hle/service/filesystem/save_data_controller.h" |
| 18 | #include "core/hle/service/glue/glue_manager.h" | 18 | #include "core/hle/service/glue/glue_manager.h" |
| 19 | #include "core/hle/service/ns/ns.h" | 19 | #include "core/hle/service/ns/application_manager_interface.h" |
| 20 | #include "core/hle/service/ns/service_getter_interface.h" | ||
| 20 | #include "core/hle/service/sm/sm.h" | 21 | #include "core/hle/service/sm/sm.h" |
| 21 | 22 | ||
| 22 | namespace Service::AM { | 23 | namespace Service::AM { |
| @@ -163,11 +164,13 @@ Result IApplicationFunctions::GetDesiredLanguage(Out<u64> out_language_code) { | |||
| 163 | 164 | ||
| 164 | // Call IApplicationManagerInterface implementation. | 165 | // Call IApplicationManagerInterface implementation. |
| 165 | auto& service_manager = system.ServiceManager(); | 166 | auto& service_manager = system.ServiceManager(); |
| 166 | auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2"); | 167 | auto ns_am2 = service_manager.GetService<NS::IServiceGetterInterface>("ns:am2"); |
| 167 | auto app_man = ns_am2->GetApplicationManagerInterface(); | 168 | |
| 169 | std::shared_ptr<NS::IApplicationManagerInterface> app_man; | ||
| 170 | R_TRY(ns_am2->GetApplicationManagerInterface(&app_man)); | ||
| 168 | 171 | ||
| 169 | // Get desired application language | 172 | // Get desired application language |
| 170 | u8 desired_language{}; | 173 | NS::ApplicationLanguage desired_language{}; |
| 171 | R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages)); | 174 | R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages)); |
| 172 | 175 | ||
| 173 | // Convert to settings language code. | 176 | // Convert to settings language code. |
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp index 776f4552b..19d6a3b89 100644 --- a/src/core/hle/service/am/service/application_proxy.cpp +++ b/src/core/hle/service/am/service/application_proxy.cpp | |||
| @@ -17,9 +17,9 @@ | |||
| 17 | namespace Service::AM { | 17 | namespace Service::AM { |
| 18 | 18 | ||
| 19 | IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, | 19 | IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, |
| 20 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger) | 20 | Kernel::KProcess* process) |
| 21 | : ServiceFramework{system_, "IApplicationProxy"}, | 21 | : ServiceFramework{system_, "IApplicationProxy"}, m_process{process}, m_applet{ |
| 22 | m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { | 22 | std::move(applet)} { |
| 23 | // clang-format off | 23 | // clang-format off |
| 24 | static const FunctionInfo functions[] = { | 24 | static const FunctionInfo functions[] = { |
| 25 | {0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, | 25 | {0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, |
| @@ -77,8 +77,7 @@ Result IApplicationProxy::GetWindowController( | |||
| 77 | Result IApplicationProxy::GetSelfController( | 77 | Result IApplicationProxy::GetSelfController( |
| 78 | Out<SharedPointer<ISelfController>> out_self_controller) { | 78 | Out<SharedPointer<ISelfController>> out_self_controller) { |
| 79 | LOG_DEBUG(Service_AM, "called"); | 79 | LOG_DEBUG(Service_AM, "called"); |
| 80 | *out_self_controller = | 80 | *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process); |
| 81 | std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger); | ||
| 82 | R_SUCCEED(); | 81 | R_SUCCEED(); |
| 83 | } | 82 | } |
| 84 | 83 | ||
diff --git a/src/core/hle/service/am/service/application_proxy.h b/src/core/hle/service/am/service/application_proxy.h index 1ebc593ba..6da350df7 100644 --- a/src/core/hle/service/am/service/application_proxy.h +++ b/src/core/hle/service/am/service/application_proxy.h | |||
| @@ -22,7 +22,7 @@ class IWindowController; | |||
| 22 | class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { | 22 | class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { |
| 23 | public: | 23 | public: |
| 24 | explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, | 24 | explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, |
| 25 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); | 25 | Kernel::KProcess* process); |
| 26 | ~IApplicationProxy(); | 26 | ~IApplicationProxy(); |
| 27 | 27 | ||
| 28 | private: | 28 | private: |
| @@ -40,7 +40,6 @@ private: | |||
| 40 | Out<SharedPointer<IApplicationFunctions>> out_application_functions); | 40 | Out<SharedPointer<IApplicationFunctions>> out_application_functions); |
| 41 | 41 | ||
| 42 | private: | 42 | private: |
| 43 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
| 44 | Kernel::KProcess* const m_process; | 43 | Kernel::KProcess* const m_process; |
| 45 | const std::shared_ptr<Applet> m_applet; | 44 | const std::shared_ptr<Applet> m_applet; |
| 46 | }; | 45 | }; |
diff --git a/src/core/hle/service/am/service/application_proxy_service.cpp b/src/core/hle/service/am/service/application_proxy_service.cpp index 36d4478df..fd66e77b9 100644 --- a/src/core/hle/service/am/service/application_proxy_service.cpp +++ b/src/core/hle/service/am/service/application_proxy_service.cpp | |||
| @@ -10,9 +10,8 @@ | |||
| 10 | 10 | ||
| 11 | namespace Service::AM { | 11 | namespace Service::AM { |
| 12 | 12 | ||
| 13 | IApplicationProxyService::IApplicationProxyService(Core::System& system_, | 13 | IApplicationProxyService::IApplicationProxyService(Core::System& system_) |
| 14 | Nvnflinger::Nvnflinger& nvnflinger) | 14 | : ServiceFramework{system_, "appletOE"} { |
| 15 | : ServiceFramework{system_, "appletOE"}, m_nvnflinger{nvnflinger} { | ||
| 16 | static const FunctionInfo functions[] = { | 15 | static const FunctionInfo functions[] = { |
| 17 | {0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"}, | 16 | {0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"}, |
| 18 | }; | 17 | }; |
| @@ -28,7 +27,7 @@ Result IApplicationProxyService::OpenApplicationProxy( | |||
| 28 | 27 | ||
| 29 | if (const auto applet = this->GetAppletFromProcessId(pid)) { | 28 | if (const auto applet = this->GetAppletFromProcessId(pid)) { |
| 30 | *out_application_proxy = | 29 | *out_application_proxy = |
| 31 | std::make_shared<IApplicationProxy>(system, applet, process_handle.Get(), m_nvnflinger); | 30 | std::make_shared<IApplicationProxy>(system, applet, process_handle.Get()); |
| 32 | R_SUCCEED(); | 31 | R_SUCCEED(); |
| 33 | } else { | 32 | } else { |
| 34 | UNIMPLEMENTED(); | 33 | UNIMPLEMENTED(); |
diff --git a/src/core/hle/service/am/service/application_proxy_service.h b/src/core/hle/service/am/service/application_proxy_service.h index 1c1d32d0b..8efafa31a 100644 --- a/src/core/hle/service/am/service/application_proxy_service.h +++ b/src/core/hle/service/am/service/application_proxy_service.h | |||
| @@ -8,10 +8,6 @@ | |||
| 8 | 8 | ||
| 9 | namespace Service { | 9 | namespace Service { |
| 10 | 10 | ||
| 11 | namespace Nvnflinger { | ||
| 12 | class Nvnflinger; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace AM { | 11 | namespace AM { |
| 16 | 12 | ||
| 17 | struct Applet; | 13 | struct Applet; |
| @@ -19,7 +15,7 @@ class IApplicationProxy; | |||
| 19 | 15 | ||
| 20 | class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> { | 16 | class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> { |
| 21 | public: | 17 | public: |
| 22 | explicit IApplicationProxyService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger); | 18 | explicit IApplicationProxyService(Core::System& system_); |
| 23 | ~IApplicationProxyService() override; | 19 | ~IApplicationProxyService() override; |
| 24 | 20 | ||
| 25 | private: | 21 | private: |
| @@ -28,7 +24,6 @@ private: | |||
| 28 | 24 | ||
| 29 | private: | 25 | private: |
| 30 | std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); | 26 | std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); |
| 31 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
| 32 | }; | 27 | }; |
| 33 | 28 | ||
| 34 | } // namespace AM | 29 | } // namespace AM |
diff --git a/src/core/hle/service/am/service/display_controller.cpp b/src/core/hle/service/am/service/display_controller.cpp index 249c73dfb..ed71f9093 100644 --- a/src/core/hle/service/am/service/display_controller.cpp +++ b/src/core/hle/service/am/service/display_controller.cpp | |||
| @@ -69,7 +69,7 @@ Result IDisplayController::ClearCaptureBuffer(bool unknown0, s32 fbshare_layer_i | |||
| 69 | Result IDisplayController::AcquireLastForegroundCaptureSharedBuffer( | 69 | Result IDisplayController::AcquireLastForegroundCaptureSharedBuffer( |
| 70 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { | 70 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { |
| 71 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 71 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 72 | R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, | 72 | R_RETURN(applet->display_layer_manager.WriteAppletCaptureBuffer(out_was_written, |
| 73 | out_fbshare_layer_index)); | 73 | out_fbshare_layer_index)); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| @@ -81,7 +81,7 @@ Result IDisplayController::ReleaseLastForegroundCaptureSharedBuffer() { | |||
| 81 | Result IDisplayController::AcquireCallerAppletCaptureSharedBuffer( | 81 | Result IDisplayController::AcquireCallerAppletCaptureSharedBuffer( |
| 82 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { | 82 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { |
| 83 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 83 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 84 | R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, | 84 | R_RETURN(applet->display_layer_manager.WriteAppletCaptureBuffer(out_was_written, |
| 85 | out_fbshare_layer_index)); | 85 | out_fbshare_layer_index)); |
| 86 | } | 86 | } |
| 87 | 87 | ||
| @@ -93,7 +93,7 @@ Result IDisplayController::ReleaseCallerAppletCaptureSharedBuffer() { | |||
| 93 | Result IDisplayController::AcquireLastApplicationCaptureSharedBuffer( | 93 | Result IDisplayController::AcquireLastApplicationCaptureSharedBuffer( |
| 94 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { | 94 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { |
| 95 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 95 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 96 | R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, | 96 | R_RETURN(applet->display_layer_manager.WriteAppletCaptureBuffer(out_was_written, |
| 97 | out_fbshare_layer_index)); | 97 | out_fbshare_layer_index)); |
| 98 | } | 98 | } |
| 99 | 99 | ||
diff --git a/src/core/hle/service/am/service/library_applet_creator.cpp b/src/core/hle/service/am/service/library_applet_creator.cpp index 166637d60..c97358d81 100644 --- a/src/core/hle/service/am/service/library_applet_creator.cpp +++ b/src/core/hle/service/am/service/library_applet_creator.cpp | |||
| @@ -135,7 +135,7 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, | |||
| 135 | case LibraryAppletMode::AllForegroundInitiallyHidden: | 135 | case LibraryAppletMode::AllForegroundInitiallyHidden: |
| 136 | applet->hid_registration.EnableAppletToGetInput(false); | 136 | applet->hid_registration.EnableAppletToGetInput(false); |
| 137 | applet->focus_state = FocusState::NotInFocus; | 137 | applet->focus_state = FocusState::NotInFocus; |
| 138 | applet->system_buffer_manager.SetWindowVisibility(false); | 138 | applet->display_layer_manager.SetWindowVisibility(false); |
| 139 | applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground); | 139 | applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground); |
| 140 | break; | 140 | break; |
| 141 | } | 141 | } |
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp index bcb44a71c..58e709347 100644 --- a/src/core/hle/service/am/service/library_applet_proxy.cpp +++ b/src/core/hle/service/am/service/library_applet_proxy.cpp | |||
| @@ -19,10 +19,9 @@ | |||
| 19 | namespace Service::AM { | 19 | namespace Service::AM { |
| 20 | 20 | ||
| 21 | ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, | 21 | ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, |
| 22 | Kernel::KProcess* process, | 22 | Kernel::KProcess* process) |
| 23 | Nvnflinger::Nvnflinger& nvnflinger) | 23 | : ServiceFramework{system_, "ILibraryAppletProxy"}, m_process{process}, m_applet{ |
| 24 | : ServiceFramework{system_, "ILibraryAppletProxy"}, | 24 | std::move(applet)} { |
| 25 | m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { | ||
| 26 | // clang-format off | 25 | // clang-format off |
| 27 | static const FunctionInfo functions[] = { | 26 | static const FunctionInfo functions[] = { |
| 28 | {0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, | 27 | {0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, |
| @@ -83,8 +82,7 @@ Result ILibraryAppletProxy::GetWindowController( | |||
| 83 | Result ILibraryAppletProxy::GetSelfController( | 82 | Result ILibraryAppletProxy::GetSelfController( |
| 84 | Out<SharedPointer<ISelfController>> out_self_controller) { | 83 | Out<SharedPointer<ISelfController>> out_self_controller) { |
| 85 | LOG_DEBUG(Service_AM, "called"); | 84 | LOG_DEBUG(Service_AM, "called"); |
| 86 | *out_self_controller = | 85 | *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process); |
| 87 | std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger); | ||
| 88 | R_SUCCEED(); | 86 | R_SUCCEED(); |
| 89 | } | 87 | } |
| 90 | 88 | ||
diff --git a/src/core/hle/service/am/service/library_applet_proxy.h b/src/core/hle/service/am/service/library_applet_proxy.h index 23e64e295..7d0714b85 100644 --- a/src/core/hle/service/am/service/library_applet_proxy.h +++ b/src/core/hle/service/am/service/library_applet_proxy.h | |||
| @@ -25,7 +25,7 @@ class IWindowController; | |||
| 25 | class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { | 25 | class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { |
| 26 | public: | 26 | public: |
| 27 | explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, | 27 | explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, |
| 28 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); | 28 | Kernel::KProcess* process); |
| 29 | ~ILibraryAppletProxy(); | 29 | ~ILibraryAppletProxy(); |
| 30 | 30 | ||
| 31 | private: | 31 | private: |
| @@ -47,7 +47,6 @@ private: | |||
| 47 | Result GetGlobalStateController( | 47 | Result GetGlobalStateController( |
| 48 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller); | 48 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller); |
| 49 | 49 | ||
| 50 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
| 51 | Kernel::KProcess* const m_process; | 50 | Kernel::KProcess* const m_process; |
| 52 | const std::shared_ptr<Applet> m_applet; | 51 | const std::shared_ptr<Applet> m_applet; |
| 53 | }; | 52 | }; |
diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.cpp b/src/core/hle/service/am/service/library_applet_self_accessor.cpp index 94bd4dae6..330eb26f0 100644 --- a/src/core/hle/service/am/service/library_applet_self_accessor.cpp +++ b/src/core/hle/service/am/service/library_applet_self_accessor.cpp | |||
| @@ -14,7 +14,8 @@ | |||
| 14 | #include "core/hle/service/cmif_serialization.h" | 14 | #include "core/hle/service/cmif_serialization.h" |
| 15 | #include "core/hle/service/filesystem/filesystem.h" | 15 | #include "core/hle/service/filesystem/filesystem.h" |
| 16 | #include "core/hle/service/glue/glue_manager.h" | 16 | #include "core/hle/service/glue/glue_manager.h" |
| 17 | #include "core/hle/service/ns/ns.h" | 17 | #include "core/hle/service/ns/application_manager_interface.h" |
| 18 | #include "core/hle/service/ns/service_getter_interface.h" | ||
| 18 | #include "core/hle/service/sm/sm.h" | 19 | #include "core/hle/service/sm/sm.h" |
| 19 | 20 | ||
| 20 | namespace Service::AM { | 21 | namespace Service::AM { |
| @@ -256,11 +257,13 @@ Result ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage( | |||
| 256 | 257 | ||
| 257 | // Call IApplicationManagerInterface implementation. | 258 | // Call IApplicationManagerInterface implementation. |
| 258 | auto& service_manager = system.ServiceManager(); | 259 | auto& service_manager = system.ServiceManager(); |
| 259 | auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2"); | 260 | auto ns_am2 = service_manager.GetService<NS::IServiceGetterInterface>("ns:am2"); |
| 260 | auto app_man = ns_am2->GetApplicationManagerInterface(); | 261 | |
| 262 | std::shared_ptr<NS::IApplicationManagerInterface> app_man; | ||
| 263 | R_TRY(ns_am2->GetApplicationManagerInterface(&app_man)); | ||
| 261 | 264 | ||
| 262 | // Get desired application language | 265 | // Get desired application language |
| 263 | u8 desired_language{}; | 266 | NS::ApplicationLanguage desired_language{}; |
| 264 | R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages)); | 267 | R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages)); |
| 265 | 268 | ||
| 266 | // Convert to settings language code. | 269 | // Convert to settings language code. |
diff --git a/src/core/hle/service/am/service/self_controller.cpp b/src/core/hle/service/am/service/self_controller.cpp index 5c4c13de1..06314407c 100644 --- a/src/core/hle/service/am/service/self_controller.cpp +++ b/src/core/hle/service/am/service/self_controller.cpp | |||
| @@ -15,9 +15,9 @@ | |||
| 15 | namespace Service::AM { | 15 | namespace Service::AM { |
| 16 | 16 | ||
| 17 | ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet, | 17 | ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet, |
| 18 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger) | 18 | Kernel::KProcess* process) |
| 19 | : ServiceFramework{system_, "ISelfController"}, | 19 | : ServiceFramework{system_, "ISelfController"}, m_process{process}, m_applet{ |
| 20 | m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { | 20 | std::move(applet)} { |
| 21 | // clang-format off | 21 | // clang-format off |
| 22 | static const FunctionInfo functions[] = { | 22 | static const FunctionInfo functions[] = { |
| 23 | {0, D<&ISelfController::Exit>, "Exit"}, | 23 | {0, D<&ISelfController::Exit>, "Exit"}, |
| @@ -72,9 +72,16 @@ ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> | |||
| 72 | // clang-format on | 72 | // clang-format on |
| 73 | 73 | ||
| 74 | RegisterHandlers(functions); | 74 | RegisterHandlers(functions); |
| 75 | |||
| 76 | std::scoped_lock lk{m_applet->lock}; | ||
| 77 | m_applet->display_layer_manager.Initialize(system, m_process, m_applet->applet_id, | ||
| 78 | m_applet->library_applet_mode); | ||
| 75 | } | 79 | } |
| 76 | 80 | ||
| 77 | ISelfController::~ISelfController() = default; | 81 | ISelfController::~ISelfController() { |
| 82 | std::scoped_lock lk{m_applet->lock}; | ||
| 83 | m_applet->display_layer_manager.Finalize(); | ||
| 84 | } | ||
| 78 | 85 | ||
| 79 | Result ISelfController::Exit() { | 86 | Result ISelfController::Exit() { |
| 80 | LOG_DEBUG(Service_AM, "called"); | 87 | LOG_DEBUG(Service_AM, "called"); |
| @@ -212,48 +219,42 @@ Result ISelfController::SetAlbumImageOrientation( | |||
| 212 | 219 | ||
| 213 | Result ISelfController::IsSystemBufferSharingEnabled() { | 220 | Result ISelfController::IsSystemBufferSharingEnabled() { |
| 214 | LOG_INFO(Service_AM, "called"); | 221 | LOG_INFO(Service_AM, "called"); |
| 215 | R_SUCCEED_IF(m_applet->system_buffer_manager.Initialize( | 222 | |
| 216 | &m_nvnflinger, m_process, m_applet->applet_id, m_applet->library_applet_mode)); | 223 | std::scoped_lock lk{m_applet->lock}; |
| 217 | R_THROW(VI::ResultOperationFailed); | 224 | R_RETURN(m_applet->display_layer_manager.IsSystemBufferSharingEnabled()); |
| 218 | } | 225 | } |
| 219 | 226 | ||
| 220 | Result ISelfController::GetSystemSharedBufferHandle(Out<u64> out_buffer_id) { | 227 | Result ISelfController::GetSystemSharedBufferHandle(Out<u64> out_buffer_id) { |
| 221 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 228 | LOG_INFO(Service_AM, "called"); |
| 222 | |||
| 223 | R_TRY(this->IsSystemBufferSharingEnabled()); | ||
| 224 | 229 | ||
| 225 | u64 layer_id; | 230 | u64 layer_id; |
| 226 | m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, &layer_id); | 231 | |
| 227 | R_SUCCEED(); | 232 | std::scoped_lock lk{m_applet->lock}; |
| 233 | R_RETURN(m_applet->display_layer_manager.GetSystemSharedLayerHandle(out_buffer_id, &layer_id)); | ||
| 228 | } | 234 | } |
| 229 | 235 | ||
| 230 | Result ISelfController::GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id) { | 236 | Result ISelfController::GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id) { |
| 231 | LOG_INFO(Service_AM, "(STUBBED) called"); | 237 | LOG_INFO(Service_AM, "called"); |
| 232 | |||
| 233 | R_TRY(this->IsSystemBufferSharingEnabled()); | ||
| 234 | 238 | ||
| 235 | m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, out_layer_id); | 239 | std::scoped_lock lk{m_applet->lock}; |
| 236 | R_SUCCEED(); | 240 | R_RETURN( |
| 241 | m_applet->display_layer_manager.GetSystemSharedLayerHandle(out_buffer_id, out_layer_id)); | ||
| 237 | } | 242 | } |
| 238 | 243 | ||
| 239 | Result ISelfController::CreateManagedDisplayLayer(Out<u64> out_layer_id) { | 244 | Result ISelfController::CreateManagedDisplayLayer(Out<u64> out_layer_id) { |
| 240 | LOG_INFO(Service_AM, "called"); | 245 | LOG_INFO(Service_AM, "called"); |
| 241 | 246 | ||
| 242 | m_applet->managed_layer_holder.Initialize(&m_nvnflinger); | 247 | std::scoped_lock lk{m_applet->lock}; |
| 243 | m_applet->managed_layer_holder.CreateManagedDisplayLayer(out_layer_id); | 248 | R_RETURN(m_applet->display_layer_manager.CreateManagedDisplayLayer(out_layer_id)); |
| 244 | |||
| 245 | R_SUCCEED(); | ||
| 246 | } | 249 | } |
| 247 | 250 | ||
| 248 | Result ISelfController::CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id, | 251 | Result ISelfController::CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id, |
| 249 | Out<u64> out_recording_layer_id) { | 252 | Out<u64> out_recording_layer_id) { |
| 250 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 253 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 251 | 254 | ||
| 252 | m_applet->managed_layer_holder.Initialize(&m_nvnflinger); | 255 | std::scoped_lock lk{m_applet->lock}; |
| 253 | m_applet->managed_layer_holder.CreateManagedDisplaySeparableLayer(out_layer_id, | 256 | R_RETURN(m_applet->display_layer_manager.CreateManagedDisplaySeparableLayer( |
| 254 | out_recording_layer_id); | 257 | out_layer_id, out_recording_layer_id)); |
| 255 | |||
| 256 | R_SUCCEED(); | ||
| 257 | } | 258 | } |
| 258 | 259 | ||
| 259 | Result ISelfController::SetHandlesRequestToDisplay(bool enable) { | 260 | Result ISelfController::SetHandlesRequestToDisplay(bool enable) { |
diff --git a/src/core/hle/service/am/service/self_controller.h b/src/core/hle/service/am/service/self_controller.h index 01fa381a3..eca083cfe 100644 --- a/src/core/hle/service/am/service/self_controller.h +++ b/src/core/hle/service/am/service/self_controller.h | |||
| @@ -23,7 +23,7 @@ struct Applet; | |||
| 23 | class ISelfController final : public ServiceFramework<ISelfController> { | 23 | class ISelfController final : public ServiceFramework<ISelfController> { |
| 24 | public: | 24 | public: |
| 25 | explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet, | 25 | explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet, |
| 26 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); | 26 | Kernel::KProcess* process); |
| 27 | ~ISelfController() override; | 27 | ~ISelfController() override; |
| 28 | 28 | ||
| 29 | private: | 29 | private: |
| @@ -64,7 +64,6 @@ private: | |||
| 64 | Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option); | 64 | Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option); |
| 65 | Result SetRecordVolumeMuted(bool muted); | 65 | Result SetRecordVolumeMuted(bool muted); |
| 66 | 66 | ||
| 67 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
| 68 | Kernel::KProcess* const m_process; | 67 | Kernel::KProcess* const m_process; |
| 69 | const std::shared_ptr<Applet> m_applet; | 68 | const std::shared_ptr<Applet> m_applet; |
| 70 | }; | 69 | }; |
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp index 5ec509d2e..d1871ef9b 100644 --- a/src/core/hle/service/am/service/system_applet_proxy.cpp +++ b/src/core/hle/service/am/service/system_applet_proxy.cpp | |||
| @@ -19,10 +19,9 @@ | |||
| 19 | namespace Service::AM { | 19 | namespace Service::AM { |
| 20 | 20 | ||
| 21 | ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, | 21 | ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, |
| 22 | Kernel::KProcess* process, | 22 | Kernel::KProcess* process) |
| 23 | Nvnflinger::Nvnflinger& nvnflinger) | 23 | : ServiceFramework{system_, "ISystemAppletProxy"}, m_process{process}, m_applet{ |
| 24 | : ServiceFramework{system_, "ISystemAppletProxy"}, | 24 | std::move(applet)} { |
| 25 | m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { | ||
| 26 | // clang-format off | 25 | // clang-format off |
| 27 | static const FunctionInfo functions[] = { | 26 | static const FunctionInfo functions[] = { |
| 28 | {0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, | 27 | {0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, |
| @@ -83,8 +82,7 @@ Result ISystemAppletProxy::GetWindowController( | |||
| 83 | Result ISystemAppletProxy::GetSelfController( | 82 | Result ISystemAppletProxy::GetSelfController( |
| 84 | Out<SharedPointer<ISelfController>> out_self_controller) { | 83 | Out<SharedPointer<ISelfController>> out_self_controller) { |
| 85 | LOG_DEBUG(Service_AM, "called"); | 84 | LOG_DEBUG(Service_AM, "called"); |
| 86 | *out_self_controller = | 85 | *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process); |
| 87 | std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger); | ||
| 88 | R_SUCCEED(); | 86 | R_SUCCEED(); |
| 89 | } | 87 | } |
| 90 | 88 | ||
diff --git a/src/core/hle/service/am/service/system_applet_proxy.h b/src/core/hle/service/am/service/system_applet_proxy.h index 3d5040315..67cd50e03 100644 --- a/src/core/hle/service/am/service/system_applet_proxy.h +++ b/src/core/hle/service/am/service/system_applet_proxy.h | |||
| @@ -25,7 +25,7 @@ class IWindowController; | |||
| 25 | class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { | 25 | class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { |
| 26 | public: | 26 | public: |
| 27 | explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet, | 27 | explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet, |
| 28 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); | 28 | Kernel::KProcess* process); |
| 29 | ~ISystemAppletProxy(); | 29 | ~ISystemAppletProxy(); |
| 30 | 30 | ||
| 31 | private: | 31 | private: |
| @@ -46,7 +46,6 @@ private: | |||
| 46 | Result GetGlobalStateController( | 46 | Result GetGlobalStateController( |
| 47 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller); | 47 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller); |
| 48 | 48 | ||
| 49 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
| 50 | Kernel::KProcess* const m_process; | 49 | Kernel::KProcess* const m_process; |
| 51 | const std::shared_ptr<Applet> m_applet; | 50 | const std::shared_ptr<Applet> m_applet; |
| 52 | }; | 51 | }; |
diff --git a/src/core/hle/service/am/service/window_controller.cpp b/src/core/hle/service/am/service/window_controller.cpp index b874ecb91..99a4f50a2 100644 --- a/src/core/hle/service/am/service/window_controller.cpp +++ b/src/core/hle/service/am/service/window_controller.cpp | |||
| @@ -63,7 +63,7 @@ Result IWindowController::RejectToChangeIntoBackground() { | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | Result IWindowController::SetAppletWindowVisibility(bool visible) { | 65 | Result IWindowController::SetAppletWindowVisibility(bool visible) { |
| 66 | m_applet->system_buffer_manager.SetWindowVisibility(visible); | 66 | m_applet->display_layer_manager.SetWindowVisibility(visible); |
| 67 | m_applet->hid_registration.EnableAppletToGetInput(visible); | 67 | m_applet->hid_registration.EnableAppletToGetInput(visible); |
| 68 | 68 | ||
| 69 | if (visible) { | 69 | if (visible) { |
diff --git a/src/core/hle/service/am/system_buffer_manager.cpp b/src/core/hle/service/am/system_buffer_manager.cpp deleted file mode 100644 index 48923fe41..000000000 --- a/src/core/hle/service/am/system_buffer_manager.cpp +++ /dev/null | |||
| @@ -1,80 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/am/system_buffer_manager.h" | ||
| 5 | #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" | ||
| 6 | #include "core/hle/service/nvnflinger/nvnflinger.h" | ||
| 7 | #include "core/hle/service/vi/vi_results.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | SystemBufferManager::SystemBufferManager() = default; | ||
| 12 | |||
| 13 | SystemBufferManager::~SystemBufferManager() { | ||
| 14 | if (!m_nvnflinger) { | ||
| 15 | return; | ||
| 16 | } | ||
| 17 | |||
| 18 | // Clean up shared layers. | ||
| 19 | if (m_buffer_sharing_enabled) { | ||
| 20 | m_nvnflinger->GetSystemBufferManager().Finalize(m_process); | ||
| 21 | } | ||
| 22 | } | ||
| 23 | |||
| 24 | bool SystemBufferManager::Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel::KProcess* process, | ||
| 25 | AppletId applet_id, LibraryAppletMode mode) { | ||
| 26 | if (m_nvnflinger) { | ||
| 27 | return m_buffer_sharing_enabled; | ||
| 28 | } | ||
| 29 | |||
| 30 | m_process = process; | ||
| 31 | m_nvnflinger = nvnflinger; | ||
| 32 | m_buffer_sharing_enabled = false; | ||
| 33 | m_system_shared_buffer_id = 0; | ||
| 34 | m_system_shared_layer_id = 0; | ||
| 35 | |||
| 36 | if (applet_id <= AppletId::Application) { | ||
| 37 | return false; | ||
| 38 | } | ||
| 39 | |||
| 40 | Nvnflinger::LayerBlending blending = Nvnflinger::LayerBlending::None; | ||
| 41 | if (mode == LibraryAppletMode::PartialForeground || | ||
| 42 | mode == LibraryAppletMode::PartialForegroundIndirectDisplay) { | ||
| 43 | blending = Nvnflinger::LayerBlending::Coverage; | ||
| 44 | } | ||
| 45 | |||
| 46 | const auto display_id = m_nvnflinger->OpenDisplay("Default").value(); | ||
| 47 | const auto res = m_nvnflinger->GetSystemBufferManager().Initialize( | ||
| 48 | m_process, &m_system_shared_buffer_id, &m_system_shared_layer_id, display_id, blending); | ||
| 49 | |||
| 50 | if (res.IsSuccess()) { | ||
| 51 | m_buffer_sharing_enabled = true; | ||
| 52 | m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible); | ||
| 53 | } | ||
| 54 | |||
| 55 | return m_buffer_sharing_enabled; | ||
| 56 | } | ||
| 57 | |||
| 58 | void SystemBufferManager::SetWindowVisibility(bool visible) { | ||
| 59 | if (m_visible == visible) { | ||
| 60 | return; | ||
| 61 | } | ||
| 62 | |||
| 63 | m_visible = visible; | ||
| 64 | |||
| 65 | if (m_nvnflinger) { | ||
| 66 | m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | Result SystemBufferManager::WriteAppletCaptureBuffer(bool* out_was_written, | ||
| 71 | s32* out_fbshare_layer_index) { | ||
| 72 | if (!m_buffer_sharing_enabled) { | ||
| 73 | return VI::ResultPermissionDenied; | ||
| 74 | } | ||
| 75 | |||
| 76 | return m_nvnflinger->GetSystemBufferManager().WriteAppletCaptureBuffer(out_was_written, | ||
| 77 | out_fbshare_layer_index); | ||
| 78 | } | ||
| 79 | |||
| 80 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/system_buffer_manager.h b/src/core/hle/service/am/system_buffer_manager.h deleted file mode 100644 index 0690f68b6..000000000 --- a/src/core/hle/service/am/system_buffer_manager.h +++ /dev/null | |||
| @@ -1,52 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <set> | ||
| 7 | |||
| 8 | #include "common/common_funcs.h" | ||
| 9 | #include "common/common_types.h" | ||
| 10 | |||
| 11 | #include "core/hle/service/am/am_types.h" | ||
| 12 | |||
| 13 | namespace Kernel { | ||
| 14 | class KProcess; | ||
| 15 | } | ||
| 16 | |||
| 17 | namespace Service::Nvnflinger { | ||
| 18 | class Nvnflinger; | ||
| 19 | } | ||
| 20 | |||
| 21 | union Result; | ||
| 22 | |||
| 23 | namespace Service::AM { | ||
| 24 | |||
| 25 | class SystemBufferManager { | ||
| 26 | public: | ||
| 27 | SystemBufferManager(); | ||
| 28 | ~SystemBufferManager(); | ||
| 29 | |||
| 30 | bool Initialize(Nvnflinger::Nvnflinger* flinger, Kernel::KProcess* process, AppletId applet_id, | ||
| 31 | LibraryAppletMode mode); | ||
| 32 | |||
| 33 | void GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id, | ||
| 34 | u64* out_system_shared_layer_id) { | ||
| 35 | *out_system_shared_buffer_id = m_system_shared_buffer_id; | ||
| 36 | *out_system_shared_layer_id = m_system_shared_layer_id; | ||
| 37 | } | ||
| 38 | |||
| 39 | void SetWindowVisibility(bool visible); | ||
| 40 | |||
| 41 | Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index); | ||
| 42 | |||
| 43 | private: | ||
| 44 | Kernel::KProcess* m_process{}; | ||
| 45 | Nvnflinger::Nvnflinger* m_nvnflinger{}; | ||
| 46 | bool m_buffer_sharing_enabled{}; | ||
| 47 | bool m_visible{true}; | ||
| 48 | u64 m_system_shared_buffer_id{}; | ||
| 49 | u64 m_system_shared_layer_id{}; | ||
| 50 | }; | ||
| 51 | |||
| 52 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/audio/audctl.cpp b/src/core/hle/service/audio/audctl.cpp deleted file mode 100644 index cf4bb4034..000000000 --- a/src/core/hle/service/audio/audctl.cpp +++ /dev/null | |||
| @@ -1,201 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/logging/log.h" | ||
| 5 | #include "core/hle/service/audio/audctl.h" | ||
| 6 | #include "core/hle/service/ipc_helpers.h" | ||
| 7 | #include "core/hle/service/set/system_settings_server.h" | ||
| 8 | #include "core/hle/service/sm/sm.h" | ||
| 9 | |||
| 10 | namespace Service::Audio { | ||
| 11 | |||
| 12 | AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} { | ||
| 13 | // clang-format off | ||
| 14 | static const FunctionInfo functions[] = { | ||
| 15 | {0, nullptr, "GetTargetVolume"}, | ||
| 16 | {1, nullptr, "SetTargetVolume"}, | ||
| 17 | {2, &AudCtl::GetTargetVolumeMin, "GetTargetVolumeMin"}, | ||
| 18 | {3, &AudCtl::GetTargetVolumeMax, "GetTargetVolumeMax"}, | ||
| 19 | {4, nullptr, "IsTargetMute"}, | ||
| 20 | {5, nullptr, "SetTargetMute"}, | ||
| 21 | {6, nullptr, "IsTargetConnected"}, | ||
| 22 | {7, nullptr, "SetDefaultTarget"}, | ||
| 23 | {8, nullptr, "GetDefaultTarget"}, | ||
| 24 | {9, &AudCtl::GetAudioOutputMode, "GetAudioOutputMode"}, | ||
| 25 | {10, &AudCtl::SetAudioOutputMode, "SetAudioOutputMode"}, | ||
| 26 | {11, nullptr, "SetForceMutePolicy"}, | ||
| 27 | {12, &AudCtl::GetForceMutePolicy, "GetForceMutePolicy"}, | ||
| 28 | {13, &AudCtl::GetOutputModeSetting, "GetOutputModeSetting"}, | ||
| 29 | {14, &AudCtl::SetOutputModeSetting, "SetOutputModeSetting"}, | ||
| 30 | {15, nullptr, "SetOutputTarget"}, | ||
| 31 | {16, nullptr, "SetInputTargetForceEnabled"}, | ||
| 32 | {17, &AudCtl::SetHeadphoneOutputLevelMode, "SetHeadphoneOutputLevelMode"}, | ||
| 33 | {18, &AudCtl::GetHeadphoneOutputLevelMode, "GetHeadphoneOutputLevelMode"}, | ||
| 34 | {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"}, | ||
| 35 | {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"}, | ||
| 36 | {21, nullptr, "GetAudioOutputTargetForPlayReport"}, | ||
| 37 | {22, nullptr, "NotifyHeadphoneVolumeWarningDisplayedEvent"}, | ||
| 38 | {23, nullptr, "SetSystemOutputMasterVolume"}, | ||
| 39 | {24, nullptr, "GetSystemOutputMasterVolume"}, | ||
| 40 | {25, nullptr, "GetAudioVolumeDataForPlayReport"}, | ||
| 41 | {26, nullptr, "UpdateHeadphoneSettings"}, | ||
| 42 | {27, nullptr, "SetVolumeMappingTableForDev"}, | ||
| 43 | {28, nullptr, "GetAudioOutputChannelCountForPlayReport"}, | ||
| 44 | {29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, | ||
| 45 | {30, &AudCtl::SetSpeakerAutoMuteEnabled, "SetSpeakerAutoMuteEnabled"}, | ||
| 46 | {31, &AudCtl::IsSpeakerAutoMuteEnabled, "IsSpeakerAutoMuteEnabled"}, | ||
| 47 | {32, nullptr, "GetActiveOutputTarget"}, | ||
| 48 | {33, nullptr, "GetTargetDeviceInfo"}, | ||
| 49 | {34, nullptr, "AcquireTargetNotification"}, | ||
| 50 | {35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"}, | ||
| 51 | {36, nullptr, "GetHearingProtectionSafeguardTimerRemainingTimeForDebug"}, | ||
| 52 | {37, nullptr, "SetHearingProtectionSafeguardEnabled"}, | ||
| 53 | {38, nullptr, "IsHearingProtectionSafeguardEnabled"}, | ||
| 54 | {39, nullptr, "IsHearingProtectionSafeguardMonitoringOutputForDebug"}, | ||
| 55 | {40, nullptr, "GetSystemInformationForDebug"}, | ||
| 56 | {41, nullptr, "SetVolumeButtonLongPressTime"}, | ||
| 57 | {42, nullptr, "SetNativeVolumeForDebug"}, | ||
| 58 | {10000, nullptr, "NotifyAudioOutputTargetForPlayReport"}, | ||
| 59 | {10001, nullptr, "NotifyAudioOutputChannelCountForPlayReport"}, | ||
| 60 | {10002, nullptr, "NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport"}, | ||
| 61 | {10100, nullptr, "GetAudioVolumeDataForPlayReport"}, | ||
| 62 | {10101, nullptr, "BindAudioVolumeUpdateEventForPlayReport"}, | ||
| 63 | {10102, nullptr, "BindAudioOutputTargetUpdateEventForPlayReport"}, | ||
| 64 | {10103, nullptr, "GetAudioOutputTargetForPlayReport"}, | ||
| 65 | {10104, nullptr, "GetAudioOutputChannelCountForPlayReport"}, | ||
| 66 | {10105, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, | ||
| 67 | {10106, nullptr, "GetDefaultAudioOutputTargetForPlayReport"}, | ||
| 68 | {50000, nullptr, "SetAnalogInputBoostGainForPrototyping"}, | ||
| 69 | }; | ||
| 70 | // clang-format on | ||
| 71 | |||
| 72 | RegisterHandlers(functions); | ||
| 73 | |||
| 74 | m_set_sys = | ||
| 75 | system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); | ||
| 76 | } | ||
| 77 | |||
| 78 | AudCtl::~AudCtl() = default; | ||
| 79 | |||
| 80 | void AudCtl::GetTargetVolumeMin(HLERequestContext& ctx) { | ||
| 81 | LOG_DEBUG(Audio, "called."); | ||
| 82 | |||
| 83 | // This service function is currently hardcoded on the | ||
| 84 | // actual console to this value (as of 8.0.0). | ||
| 85 | constexpr s32 target_min_volume = 0; | ||
| 86 | |||
| 87 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 88 | rb.Push(ResultSuccess); | ||
| 89 | rb.Push(target_min_volume); | ||
| 90 | } | ||
| 91 | |||
| 92 | void AudCtl::GetTargetVolumeMax(HLERequestContext& ctx) { | ||
| 93 | LOG_DEBUG(Audio, "called."); | ||
| 94 | |||
| 95 | // This service function is currently hardcoded on the | ||
| 96 | // actual console to this value (as of 8.0.0). | ||
| 97 | constexpr s32 target_max_volume = 15; | ||
| 98 | |||
| 99 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 100 | rb.Push(ResultSuccess); | ||
| 101 | rb.Push(target_max_volume); | ||
| 102 | } | ||
| 103 | |||
| 104 | void AudCtl::GetAudioOutputMode(HLERequestContext& ctx) { | ||
| 105 | IPC::RequestParser rp{ctx}; | ||
| 106 | const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()}; | ||
| 107 | |||
| 108 | Set::AudioOutputMode output_mode{}; | ||
| 109 | const auto result = m_set_sys->GetAudioOutputMode(&output_mode, target); | ||
| 110 | |||
| 111 | LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); | ||
| 112 | |||
| 113 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 114 | rb.Push(result); | ||
| 115 | rb.PushEnum(output_mode); | ||
| 116 | } | ||
| 117 | |||
| 118 | void AudCtl::SetAudioOutputMode(HLERequestContext& ctx) { | ||
| 119 | IPC::RequestParser rp{ctx}; | ||
| 120 | const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()}; | ||
| 121 | const auto output_mode{rp.PopEnum<Set::AudioOutputMode>()}; | ||
| 122 | |||
| 123 | const auto result = m_set_sys->SetAudioOutputMode(target, output_mode); | ||
| 124 | |||
| 125 | LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); | ||
| 126 | |||
| 127 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 128 | rb.Push(result); | ||
| 129 | } | ||
| 130 | |||
| 131 | void AudCtl::GetForceMutePolicy(HLERequestContext& ctx) { | ||
| 132 | LOG_WARNING(Audio, "(STUBBED) called"); | ||
| 133 | |||
| 134 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 135 | rb.Push(ResultSuccess); | ||
| 136 | rb.PushEnum(ForceMutePolicy::Disable); | ||
| 137 | } | ||
| 138 | |||
| 139 | void AudCtl::GetOutputModeSetting(HLERequestContext& ctx) { | ||
| 140 | IPC::RequestParser rp{ctx}; | ||
| 141 | const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()}; | ||
| 142 | |||
| 143 | LOG_WARNING(Audio, "(STUBBED) called, target={}", target); | ||
| 144 | |||
| 145 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 146 | rb.Push(ResultSuccess); | ||
| 147 | rb.PushEnum(Set::AudioOutputMode::ch_7_1); | ||
| 148 | } | ||
| 149 | |||
| 150 | void AudCtl::SetOutputModeSetting(HLERequestContext& ctx) { | ||
| 151 | IPC::RequestParser rp{ctx}; | ||
| 152 | const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()}; | ||
| 153 | const auto output_mode{rp.PopEnum<Set::AudioOutputMode>()}; | ||
| 154 | |||
| 155 | LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); | ||
| 156 | |||
| 157 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 158 | rb.Push(ResultSuccess); | ||
| 159 | } | ||
| 160 | |||
| 161 | void AudCtl::SetHeadphoneOutputLevelMode(HLERequestContext& ctx) { | ||
| 162 | LOG_WARNING(Audio, "(STUBBED) called"); | ||
| 163 | |||
| 164 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 165 | rb.Push(ResultSuccess); | ||
| 166 | } | ||
| 167 | |||
| 168 | void AudCtl::GetHeadphoneOutputLevelMode(HLERequestContext& ctx) { | ||
| 169 | LOG_WARNING(Audio, "(STUBBED) called"); | ||
| 170 | |||
| 171 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 172 | rb.Push(ResultSuccess); | ||
| 173 | rb.PushEnum(HeadphoneOutputLevelMode::Normal); | ||
| 174 | } | ||
| 175 | |||
| 176 | void AudCtl::SetSpeakerAutoMuteEnabled(HLERequestContext& ctx) { | ||
| 177 | IPC::RequestParser rp{ctx}; | ||
| 178 | const auto is_speaker_auto_mute_enabled{rp.Pop<bool>()}; | ||
| 179 | |||
| 180 | LOG_WARNING(Audio, "(STUBBED) called, is_speaker_auto_mute_enabled={}", | ||
| 181 | is_speaker_auto_mute_enabled); | ||
| 182 | |||
| 183 | const auto result = m_set_sys->SetSpeakerAutoMuteFlag(is_speaker_auto_mute_enabled); | ||
| 184 | |||
| 185 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 186 | rb.Push(result); | ||
| 187 | } | ||
| 188 | |||
| 189 | void AudCtl::IsSpeakerAutoMuteEnabled(HLERequestContext& ctx) { | ||
| 190 | bool is_speaker_auto_mute_enabled{}; | ||
| 191 | const auto result = m_set_sys->GetSpeakerAutoMuteFlag(&is_speaker_auto_mute_enabled); | ||
| 192 | |||
| 193 | LOG_WARNING(Audio, "(STUBBED) called, is_speaker_auto_mute_enabled={}", | ||
| 194 | is_speaker_auto_mute_enabled); | ||
| 195 | |||
| 196 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 197 | rb.Push(result); | ||
| 198 | rb.Push<u8>(is_speaker_auto_mute_enabled); | ||
| 199 | } | ||
| 200 | |||
| 201 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/audctl.h b/src/core/hle/service/audio/audctl.h deleted file mode 100644 index 4c90ead70..000000000 --- a/src/core/hle/service/audio/audctl.h +++ /dev/null | |||
| @@ -1,50 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Core { | ||
| 9 | class System; | ||
| 10 | } | ||
| 11 | |||
| 12 | namespace Service::Set { | ||
| 13 | class ISystemSettingsServer; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace Service::Audio { | ||
| 17 | |||
| 18 | class AudCtl final : public ServiceFramework<AudCtl> { | ||
| 19 | public: | ||
| 20 | explicit AudCtl(Core::System& system_); | ||
| 21 | ~AudCtl() override; | ||
| 22 | |||
| 23 | private: | ||
| 24 | enum class ForceMutePolicy { | ||
| 25 | Disable, | ||
| 26 | SpeakerMuteOnHeadphoneUnplugged, | ||
| 27 | }; | ||
| 28 | |||
| 29 | enum class HeadphoneOutputLevelMode { | ||
| 30 | Normal, | ||
| 31 | HighPower, | ||
| 32 | }; | ||
| 33 | |||
| 34 | void GetTargetVolumeMin(HLERequestContext& ctx); | ||
| 35 | void GetTargetVolumeMax(HLERequestContext& ctx); | ||
| 36 | void GetAudioOutputMode(HLERequestContext& ctx); | ||
| 37 | void SetAudioOutputMode(HLERequestContext& ctx); | ||
| 38 | void GetForceMutePolicy(HLERequestContext& ctx); | ||
| 39 | void GetOutputModeSetting(HLERequestContext& ctx); | ||
| 40 | void SetOutputModeSetting(HLERequestContext& ctx); | ||
| 41 | void SetHeadphoneOutputLevelMode(HLERequestContext& ctx); | ||
| 42 | void GetHeadphoneOutputLevelMode(HLERequestContext& ctx); | ||
| 43 | void SetSpeakerAutoMuteEnabled(HLERequestContext& ctx); | ||
| 44 | void IsSpeakerAutoMuteEnabled(HLERequestContext& ctx); | ||
| 45 | void AcquireTargetNotification(HLERequestContext& ctx); | ||
| 46 | |||
| 47 | std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; | ||
| 48 | }; | ||
| 49 | |||
| 50 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp index dccd16309..44af030eb 100644 --- a/src/core/hle/service/audio/audio.cpp +++ b/src/core/hle/service/audio/audio.cpp | |||
| @@ -2,9 +2,9 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/core.h" | 4 | #include "core/core.h" |
| 5 | #include "core/hle/service/audio/audctl.h" | ||
| 6 | #include "core/hle/service/audio/audin_u.h" | 5 | #include "core/hle/service/audio/audin_u.h" |
| 7 | #include "core/hle/service/audio/audio.h" | 6 | #include "core/hle/service/audio/audio.h" |
| 7 | #include "core/hle/service/audio/audio_controller.h" | ||
| 8 | #include "core/hle/service/audio/audout_u.h" | 8 | #include "core/hle/service/audio/audout_u.h" |
| 9 | #include "core/hle/service/audio/audrec_a.h" | 9 | #include "core/hle/service/audio/audrec_a.h" |
| 10 | #include "core/hle/service/audio/audrec_u.h" | 10 | #include "core/hle/service/audio/audrec_u.h" |
| @@ -18,7 +18,7 @@ namespace Service::Audio { | |||
| 18 | void LoopProcess(Core::System& system) { | 18 | void LoopProcess(Core::System& system) { |
| 19 | auto server_manager = std::make_unique<ServerManager>(system); | 19 | auto server_manager = std::make_unique<ServerManager>(system); |
| 20 | 20 | ||
| 21 | server_manager->RegisterNamedService("audctl", std::make_shared<AudCtl>(system)); | 21 | server_manager->RegisterNamedService("audctl", std::make_shared<IAudioController>(system)); |
| 22 | server_manager->RegisterNamedService("audout:u", std::make_shared<AudOutU>(system)); | 22 | server_manager->RegisterNamedService("audout:u", std::make_shared<AudOutU>(system)); |
| 23 | server_manager->RegisterNamedService("audin:u", std::make_shared<AudInU>(system)); | 23 | server_manager->RegisterNamedService("audin:u", std::make_shared<AudInU>(system)); |
| 24 | server_manager->RegisterNamedService("audrec:a", std::make_shared<AudRecA>(system)); | 24 | server_manager->RegisterNamedService("audrec:a", std::make_shared<AudRecA>(system)); |
diff --git a/src/core/hle/service/audio/audio_controller.cpp b/src/core/hle/service/audio/audio_controller.cpp new file mode 100644 index 000000000..a6da66d0f --- /dev/null +++ b/src/core/hle/service/audio/audio_controller.cpp | |||
| @@ -0,0 +1,174 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/logging/log.h" | ||
| 5 | #include "core/hle/service/audio/audio_controller.h" | ||
| 6 | #include "core/hle/service/cmif_serialization.h" | ||
| 7 | #include "core/hle/service/ipc_helpers.h" | ||
| 8 | #include "core/hle/service/set/system_settings_server.h" | ||
| 9 | #include "core/hle/service/sm/sm.h" | ||
| 10 | |||
| 11 | namespace Service::Audio { | ||
| 12 | |||
| 13 | IAudioController::IAudioController(Core::System& system_) | ||
| 14 | : ServiceFramework{system_, "audctl"}, service_context{system, "audctl"} { | ||
| 15 | // clang-format off | ||
| 16 | static const FunctionInfo functions[] = { | ||
| 17 | {0, nullptr, "GetTargetVolume"}, | ||
| 18 | {1, nullptr, "SetTargetVolume"}, | ||
| 19 | {2, C<&IAudioController::GetTargetVolumeMin>, "GetTargetVolumeMin"}, | ||
| 20 | {3, C<&IAudioController::GetTargetVolumeMax>, "GetTargetVolumeMax"}, | ||
| 21 | {4, nullptr, "IsTargetMute"}, | ||
| 22 | {5, nullptr, "SetTargetMute"}, | ||
| 23 | {6, nullptr, "IsTargetConnected"}, | ||
| 24 | {7, nullptr, "SetDefaultTarget"}, | ||
| 25 | {8, nullptr, "GetDefaultTarget"}, | ||
| 26 | {9, C<&IAudioController::GetAudioOutputMode>, "GetAudioOutputMode"}, | ||
| 27 | {10, C<&IAudioController::SetAudioOutputMode>, "SetAudioOutputMode"}, | ||
| 28 | {11, nullptr, "SetForceMutePolicy"}, | ||
| 29 | {12, C<&IAudioController::GetForceMutePolicy>, "GetForceMutePolicy"}, | ||
| 30 | {13, C<&IAudioController::GetOutputModeSetting>, "GetOutputModeSetting"}, | ||
| 31 | {14, C<&IAudioController::SetOutputModeSetting>, "SetOutputModeSetting"}, | ||
| 32 | {15, nullptr, "SetOutputTarget"}, | ||
| 33 | {16, nullptr, "SetInputTargetForceEnabled"}, | ||
| 34 | {17, C<&IAudioController::SetHeadphoneOutputLevelMode>, "SetHeadphoneOutputLevelMode"}, | ||
| 35 | {18, C<&IAudioController::GetHeadphoneOutputLevelMode>, "GetHeadphoneOutputLevelMode"}, | ||
| 36 | {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"}, | ||
| 37 | {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"}, | ||
| 38 | {21, nullptr, "GetAudioOutputTargetForPlayReport"}, | ||
| 39 | {22, nullptr, "NotifyHeadphoneVolumeWarningDisplayedEvent"}, | ||
| 40 | {23, nullptr, "SetSystemOutputMasterVolume"}, | ||
| 41 | {24, nullptr, "GetSystemOutputMasterVolume"}, | ||
| 42 | {25, nullptr, "GetAudioVolumeDataForPlayReport"}, | ||
| 43 | {26, nullptr, "UpdateHeadphoneSettings"}, | ||
| 44 | {27, nullptr, "SetVolumeMappingTableForDev"}, | ||
| 45 | {28, nullptr, "GetAudioOutputChannelCountForPlayReport"}, | ||
| 46 | {29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, | ||
| 47 | {30, C<&IAudioController::SetSpeakerAutoMuteEnabled>, "SetSpeakerAutoMuteEnabled"}, | ||
| 48 | {31, C<&IAudioController::IsSpeakerAutoMuteEnabled>, "IsSpeakerAutoMuteEnabled"}, | ||
| 49 | {32, nullptr, "GetActiveOutputTarget"}, | ||
| 50 | {33, nullptr, "GetTargetDeviceInfo"}, | ||
| 51 | {34, C<&IAudioController::AcquireTargetNotification>, "AcquireTargetNotification"}, | ||
| 52 | {35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"}, | ||
| 53 | {36, nullptr, "GetHearingProtectionSafeguardTimerRemainingTimeForDebug"}, | ||
| 54 | {37, nullptr, "SetHearingProtectionSafeguardEnabled"}, | ||
| 55 | {38, nullptr, "IsHearingProtectionSafeguardEnabled"}, | ||
| 56 | {39, nullptr, "IsHearingProtectionSafeguardMonitoringOutputForDebug"}, | ||
| 57 | {40, nullptr, "GetSystemInformationForDebug"}, | ||
| 58 | {41, nullptr, "SetVolumeButtonLongPressTime"}, | ||
| 59 | {42, nullptr, "SetNativeVolumeForDebug"}, | ||
| 60 | {10000, nullptr, "NotifyAudioOutputTargetForPlayReport"}, | ||
| 61 | {10001, nullptr, "NotifyAudioOutputChannelCountForPlayReport"}, | ||
| 62 | {10002, nullptr, "NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport"}, | ||
| 63 | {10100, nullptr, "GetAudioVolumeDataForPlayReport"}, | ||
| 64 | {10101, nullptr, "BindAudioVolumeUpdateEventForPlayReport"}, | ||
| 65 | {10102, nullptr, "BindAudioOutputTargetUpdateEventForPlayReport"}, | ||
| 66 | {10103, nullptr, "GetAudioOutputTargetForPlayReport"}, | ||
| 67 | {10104, nullptr, "GetAudioOutputChannelCountForPlayReport"}, | ||
| 68 | {10105, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, | ||
| 69 | {10106, nullptr, "GetDefaultAudioOutputTargetForPlayReport"}, | ||
| 70 | {50000, nullptr, "SetAnalogInputBoostGainForPrototyping"}, | ||
| 71 | }; | ||
| 72 | // clang-format on | ||
| 73 | |||
| 74 | RegisterHandlers(functions); | ||
| 75 | |||
| 76 | m_set_sys = | ||
| 77 | system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); | ||
| 78 | notification_event = service_context.CreateEvent("IAudioController:NotificationEvent"); | ||
| 79 | } | ||
| 80 | |||
| 81 | IAudioController::~IAudioController() { | ||
| 82 | service_context.CloseEvent(notification_event); | ||
| 83 | }; | ||
| 84 | |||
| 85 | Result IAudioController::GetTargetVolumeMin(Out<s32> out_target_min_volume) { | ||
| 86 | LOG_DEBUG(Audio, "called."); | ||
| 87 | |||
| 88 | // This service function is currently hardcoded on the | ||
| 89 | // actual console to this value (as of 8.0.0). | ||
| 90 | *out_target_min_volume = 0; | ||
| 91 | R_SUCCEED(); | ||
| 92 | } | ||
| 93 | |||
| 94 | Result IAudioController::GetTargetVolumeMax(Out<s32> out_target_max_volume) { | ||
| 95 | LOG_DEBUG(Audio, "called."); | ||
| 96 | |||
| 97 | // This service function is currently hardcoded on the | ||
| 98 | // actual console to this value (as of 8.0.0). | ||
| 99 | *out_target_max_volume = 15; | ||
| 100 | R_SUCCEED(); | ||
| 101 | } | ||
| 102 | |||
| 103 | Result IAudioController::GetAudioOutputMode(Out<Set::AudioOutputMode> out_output_mode, | ||
| 104 | Set::AudioOutputModeTarget target) { | ||
| 105 | const auto result = m_set_sys->GetAudioOutputMode(out_output_mode, target); | ||
| 106 | |||
| 107 | LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, *out_output_mode); | ||
| 108 | R_RETURN(result); | ||
| 109 | } | ||
| 110 | |||
| 111 | Result IAudioController::SetAudioOutputMode(Set::AudioOutputModeTarget target, | ||
| 112 | Set::AudioOutputMode output_mode) { | ||
| 113 | LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); | ||
| 114 | |||
| 115 | R_RETURN(m_set_sys->SetAudioOutputMode(target, output_mode)); | ||
| 116 | } | ||
| 117 | |||
| 118 | Result IAudioController::GetForceMutePolicy(Out<ForceMutePolicy> out_mute_policy) { | ||
| 119 | LOG_WARNING(Audio, "(STUBBED) called"); | ||
| 120 | |||
| 121 | // Removed on FW 13.2.1+ | ||
| 122 | *out_mute_policy = ForceMutePolicy::Disable; | ||
| 123 | R_SUCCEED(); | ||
| 124 | } | ||
| 125 | |||
| 126 | Result IAudioController::GetOutputModeSetting(Out<Set::AudioOutputMode> out_output_mode, | ||
| 127 | Set::AudioOutputModeTarget target) { | ||
| 128 | LOG_WARNING(Audio, "(STUBBED) called, target={}", target); | ||
| 129 | |||
| 130 | *out_output_mode = Set::AudioOutputMode::ch_7_1; | ||
| 131 | R_SUCCEED(); | ||
| 132 | } | ||
| 133 | |||
| 134 | Result IAudioController::SetOutputModeSetting(Set::AudioOutputModeTarget target, | ||
| 135 | Set::AudioOutputMode output_mode) { | ||
| 136 | LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); | ||
| 137 | R_SUCCEED(); | ||
| 138 | } | ||
| 139 | |||
| 140 | Result IAudioController::SetHeadphoneOutputLevelMode(HeadphoneOutputLevelMode output_level_mode) { | ||
| 141 | LOG_WARNING(Audio, "(STUBBED) called"); | ||
| 142 | R_SUCCEED(); | ||
| 143 | } | ||
| 144 | |||
| 145 | Result IAudioController::GetHeadphoneOutputLevelMode( | ||
| 146 | Out<HeadphoneOutputLevelMode> out_output_level_mode) { | ||
| 147 | LOG_INFO(Audio, "called"); | ||
| 148 | |||
| 149 | *out_output_level_mode = HeadphoneOutputLevelMode::Normal; | ||
| 150 | R_SUCCEED(); | ||
| 151 | } | ||
| 152 | |||
| 153 | Result IAudioController::SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled) { | ||
| 154 | LOG_INFO(Audio, "called, is_speaker_auto_mute_enabled={}", is_speaker_auto_mute_enabled); | ||
| 155 | |||
| 156 | R_RETURN(m_set_sys->SetSpeakerAutoMuteFlag(is_speaker_auto_mute_enabled)); | ||
| 157 | } | ||
| 158 | |||
| 159 | Result IAudioController::IsSpeakerAutoMuteEnabled(Out<bool> out_is_speaker_auto_mute_enabled) { | ||
| 160 | const auto result = m_set_sys->GetSpeakerAutoMuteFlag(out_is_speaker_auto_mute_enabled); | ||
| 161 | |||
| 162 | LOG_INFO(Audio, "called, is_speaker_auto_mute_enabled={}", *out_is_speaker_auto_mute_enabled); | ||
| 163 | R_RETURN(result); | ||
| 164 | } | ||
| 165 | |||
| 166 | Result IAudioController::AcquireTargetNotification( | ||
| 167 | OutCopyHandle<Kernel::KReadableEvent> out_notification_event) { | ||
| 168 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 169 | |||
| 170 | *out_notification_event = ¬ification_event->GetReadableEvent(); | ||
| 171 | R_SUCCEED(); | ||
| 172 | } | ||
| 173 | |||
| 174 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/audio_controller.h b/src/core/hle/service/audio/audio_controller.h new file mode 100644 index 000000000..9e8514373 --- /dev/null +++ b/src/core/hle/service/audio/audio_controller.h | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | #include "core/hle/service/set/settings_types.h" | ||
| 9 | |||
| 10 | namespace Core { | ||
| 11 | class System; | ||
| 12 | } | ||
| 13 | |||
| 14 | namespace Service::Set { | ||
| 15 | class ISystemSettingsServer; | ||
| 16 | } | ||
| 17 | |||
| 18 | namespace Service::Audio { | ||
| 19 | |||
| 20 | class IAudioController final : public ServiceFramework<IAudioController> { | ||
| 21 | public: | ||
| 22 | explicit IAudioController(Core::System& system_); | ||
| 23 | ~IAudioController() override; | ||
| 24 | |||
| 25 | private: | ||
| 26 | enum class ForceMutePolicy { | ||
| 27 | Disable, | ||
| 28 | SpeakerMuteOnHeadphoneUnplugged, | ||
| 29 | }; | ||
| 30 | |||
| 31 | enum class HeadphoneOutputLevelMode { | ||
| 32 | Normal, | ||
| 33 | HighPower, | ||
| 34 | }; | ||
| 35 | |||
| 36 | Result GetTargetVolumeMin(Out<s32> out_target_min_volume); | ||
| 37 | Result GetTargetVolumeMax(Out<s32> out_target_max_volume); | ||
| 38 | Result GetAudioOutputMode(Out<Set::AudioOutputMode> out_output_mode, | ||
| 39 | Set::AudioOutputModeTarget target); | ||
| 40 | Result SetAudioOutputMode(Set::AudioOutputModeTarget target, Set::AudioOutputMode output_mode); | ||
| 41 | Result GetForceMutePolicy(Out<ForceMutePolicy> out_mute_policy); | ||
| 42 | Result GetOutputModeSetting(Out<Set::AudioOutputMode> out_output_mode, | ||
| 43 | Set::AudioOutputModeTarget target); | ||
| 44 | Result SetOutputModeSetting(Set::AudioOutputModeTarget target, | ||
| 45 | Set::AudioOutputMode output_mode); | ||
| 46 | Result SetHeadphoneOutputLevelMode(HeadphoneOutputLevelMode output_level_mode); | ||
| 47 | Result GetHeadphoneOutputLevelMode(Out<HeadphoneOutputLevelMode> out_output_level_mode); | ||
| 48 | Result SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled); | ||
| 49 | Result IsSpeakerAutoMuteEnabled(Out<bool> out_is_speaker_auto_mute_enabled); | ||
| 50 | Result AcquireTargetNotification(OutCopyHandle<Kernel::KReadableEvent> out_notification_event); | ||
| 51 | |||
| 52 | KernelHelpers::ServiceContext service_context; | ||
| 53 | |||
| 54 | Kernel::KEvent* notification_event; | ||
| 55 | std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; | ||
| 56 | }; | ||
| 57 | |||
| 58 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp index 2dc23e674..d120dade8 100644 --- a/src/core/hle/service/btm/btm.cpp +++ b/src/core/hle/service/btm/btm.cpp | |||
| @@ -3,141 +3,18 @@ | |||
| 3 | 3 | ||
| 4 | #include <memory> | 4 | #include <memory> |
| 5 | 5 | ||
| 6 | #include "common/logging/log.h" | ||
| 7 | #include "core/core.h" | ||
| 8 | #include "core/hle/kernel/k_event.h" | ||
| 9 | #include "core/hle/service/btm/btm.h" | 6 | #include "core/hle/service/btm/btm.h" |
| 10 | #include "core/hle/service/ipc_helpers.h" | 7 | #include "core/hle/service/btm/btm_debug.h" |
| 11 | #include "core/hle/service/kernel_helpers.h" | 8 | #include "core/hle/service/btm/btm_system.h" |
| 9 | #include "core/hle/service/btm/btm_user.h" | ||
| 12 | #include "core/hle/service/server_manager.h" | 10 | #include "core/hle/service/server_manager.h" |
| 13 | #include "core/hle/service/service.h" | 11 | #include "core/hle/service/service.h" |
| 14 | 12 | ||
| 15 | namespace Service::BTM { | 13 | namespace Service::BTM { |
| 16 | 14 | ||
| 17 | class IBtmUserCore final : public ServiceFramework<IBtmUserCore> { | 15 | class IBtm final : public ServiceFramework<IBtm> { |
| 18 | public: | 16 | public: |
| 19 | explicit IBtmUserCore(Core::System& system_) | 17 | explicit IBtm(Core::System& system_) : ServiceFramework{system_, "btm"} { |
| 20 | : ServiceFramework{system_, "IBtmUserCore"}, service_context{system_, "IBtmUserCore"} { | ||
| 21 | // clang-format off | ||
| 22 | static const FunctionInfo functions[] = { | ||
| 23 | {0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"}, | ||
| 24 | {1, nullptr, "GetBleScanFilterParameter"}, | ||
| 25 | {2, nullptr, "GetBleScanFilterParameter2"}, | ||
| 26 | {3, nullptr, "StartBleScanForGeneral"}, | ||
| 27 | {4, nullptr, "StopBleScanForGeneral"}, | ||
| 28 | {5, nullptr, "GetBleScanResultsForGeneral"}, | ||
| 29 | {6, nullptr, "StartBleScanForPaired"}, | ||
| 30 | {7, nullptr, "StopBleScanForPaired"}, | ||
| 31 | {8, nullptr, "StartBleScanForSmartDevice"}, | ||
| 32 | {9, nullptr, "StopBleScanForSmartDevice"}, | ||
| 33 | {10, nullptr, "GetBleScanResultsForSmartDevice"}, | ||
| 34 | {17, &IBtmUserCore::AcquireBleConnectionEvent, "AcquireBleConnectionEvent"}, | ||
| 35 | {18, nullptr, "BleConnect"}, | ||
| 36 | {19, nullptr, "BleDisconnect"}, | ||
| 37 | {20, nullptr, "BleGetConnectionState"}, | ||
| 38 | {21, nullptr, "AcquireBlePairingEvent"}, | ||
| 39 | {22, nullptr, "BlePairDevice"}, | ||
| 40 | {23, nullptr, "BleUnPairDevice"}, | ||
| 41 | {24, nullptr, "BleUnPairDevice2"}, | ||
| 42 | {25, nullptr, "BleGetPairedDevices"}, | ||
| 43 | {26, &IBtmUserCore::AcquireBleServiceDiscoveryEvent, "AcquireBleServiceDiscoveryEvent"}, | ||
| 44 | {27, nullptr, "GetGattServices"}, | ||
| 45 | {28, nullptr, "GetGattService"}, | ||
| 46 | {29, nullptr, "GetGattIncludedServices"}, | ||
| 47 | {30, nullptr, "GetBelongingGattService"}, | ||
| 48 | {31, nullptr, "GetGattCharacteristics"}, | ||
| 49 | {32, nullptr, "GetGattDescriptors"}, | ||
| 50 | {33, &IBtmUserCore::AcquireBleMtuConfigEvent, "AcquireBleMtuConfigEvent"}, | ||
| 51 | {34, nullptr, "ConfigureBleMtu"}, | ||
| 52 | {35, nullptr, "GetBleMtu"}, | ||
| 53 | {36, nullptr, "RegisterBleGattDataPath"}, | ||
| 54 | {37, nullptr, "UnregisterBleGattDataPath"}, | ||
| 55 | }; | ||
| 56 | // clang-format on | ||
| 57 | RegisterHandlers(functions); | ||
| 58 | |||
| 59 | scan_event = service_context.CreateEvent("IBtmUserCore:ScanEvent"); | ||
| 60 | connection_event = service_context.CreateEvent("IBtmUserCore:ConnectionEvent"); | ||
| 61 | service_discovery_event = service_context.CreateEvent("IBtmUserCore:DiscoveryEvent"); | ||
| 62 | config_event = service_context.CreateEvent("IBtmUserCore:ConfigEvent"); | ||
| 63 | } | ||
| 64 | |||
| 65 | ~IBtmUserCore() override { | ||
| 66 | service_context.CloseEvent(scan_event); | ||
| 67 | service_context.CloseEvent(connection_event); | ||
| 68 | service_context.CloseEvent(service_discovery_event); | ||
| 69 | service_context.CloseEvent(config_event); | ||
| 70 | } | ||
| 71 | |||
| 72 | private: | ||
| 73 | void AcquireBleScanEvent(HLERequestContext& ctx) { | ||
| 74 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 75 | |||
| 76 | IPC::ResponseBuilder rb{ctx, 3, 1}; | ||
| 77 | rb.Push(ResultSuccess); | ||
| 78 | rb.Push(true); | ||
| 79 | rb.PushCopyObjects(scan_event->GetReadableEvent()); | ||
| 80 | } | ||
| 81 | |||
| 82 | void AcquireBleConnectionEvent(HLERequestContext& ctx) { | ||
| 83 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 84 | |||
| 85 | IPC::ResponseBuilder rb{ctx, 3, 1}; | ||
| 86 | rb.Push(ResultSuccess); | ||
| 87 | rb.Push(true); | ||
| 88 | rb.PushCopyObjects(connection_event->GetReadableEvent()); | ||
| 89 | } | ||
| 90 | |||
| 91 | void AcquireBleServiceDiscoveryEvent(HLERequestContext& ctx) { | ||
| 92 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 93 | |||
| 94 | IPC::ResponseBuilder rb{ctx, 3, 1}; | ||
| 95 | rb.Push(ResultSuccess); | ||
| 96 | rb.Push(true); | ||
| 97 | rb.PushCopyObjects(service_discovery_event->GetReadableEvent()); | ||
| 98 | } | ||
| 99 | |||
| 100 | void AcquireBleMtuConfigEvent(HLERequestContext& ctx) { | ||
| 101 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 102 | |||
| 103 | IPC::ResponseBuilder rb{ctx, 3, 1}; | ||
| 104 | rb.Push(ResultSuccess); | ||
| 105 | rb.Push(true); | ||
| 106 | rb.PushCopyObjects(config_event->GetReadableEvent()); | ||
| 107 | } | ||
| 108 | |||
| 109 | KernelHelpers::ServiceContext service_context; | ||
| 110 | |||
| 111 | Kernel::KEvent* scan_event; | ||
| 112 | Kernel::KEvent* connection_event; | ||
| 113 | Kernel::KEvent* service_discovery_event; | ||
| 114 | Kernel::KEvent* config_event; | ||
| 115 | }; | ||
| 116 | |||
| 117 | class BTM_USR final : public ServiceFramework<BTM_USR> { | ||
| 118 | public: | ||
| 119 | explicit BTM_USR(Core::System& system_) : ServiceFramework{system_, "btm:u"} { | ||
| 120 | // clang-format off | ||
| 121 | static const FunctionInfo functions[] = { | ||
| 122 | {0, &BTM_USR::GetCore, "GetCore"}, | ||
| 123 | }; | ||
| 124 | // clang-format on | ||
| 125 | RegisterHandlers(functions); | ||
| 126 | } | ||
| 127 | |||
| 128 | private: | ||
| 129 | void GetCore(HLERequestContext& ctx) { | ||
| 130 | LOG_WARNING(Service_BTM, "called"); | ||
| 131 | |||
| 132 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 133 | rb.Push(ResultSuccess); | ||
| 134 | rb.PushIpcInterface<IBtmUserCore>(system); | ||
| 135 | } | ||
| 136 | }; | ||
| 137 | |||
| 138 | class BTM final : public ServiceFramework<BTM> { | ||
| 139 | public: | ||
| 140 | explicit BTM(Core::System& system_) : ServiceFramework{system_, "btm"} { | ||
| 141 | // clang-format off | 18 | // clang-format off |
| 142 | static const FunctionInfo functions[] = { | 19 | static const FunctionInfo functions[] = { |
| 143 | {0, nullptr, "GetState"}, | 20 | {0, nullptr, "GetState"}, |
| @@ -232,144 +109,13 @@ public: | |||
| 232 | } | 109 | } |
| 233 | }; | 110 | }; |
| 234 | 111 | ||
| 235 | class BTM_DBG final : public ServiceFramework<BTM_DBG> { | ||
| 236 | public: | ||
| 237 | explicit BTM_DBG(Core::System& system_) : ServiceFramework{system_, "btm:dbg"} { | ||
| 238 | // clang-format off | ||
| 239 | static const FunctionInfo functions[] = { | ||
| 240 | {0, nullptr, "AcquireDiscoveryEvent"}, | ||
| 241 | {1, nullptr, "StartDiscovery"}, | ||
| 242 | {2, nullptr, "CancelDiscovery"}, | ||
| 243 | {3, nullptr, "GetDeviceProperty"}, | ||
| 244 | {4, nullptr, "CreateBond"}, | ||
| 245 | {5, nullptr, "CancelBond"}, | ||
| 246 | {6, nullptr, "SetTsiMode"}, | ||
| 247 | {7, nullptr, "GeneralTest"}, | ||
| 248 | {8, nullptr, "HidConnect"}, | ||
| 249 | {9, nullptr, "GeneralGet"}, | ||
| 250 | {10, nullptr, "GetGattClientDisconnectionReason"}, | ||
| 251 | {11, nullptr, "GetBleConnectionParameter"}, | ||
| 252 | {12, nullptr, "GetBleConnectionParameterRequest"}, | ||
| 253 | {13, nullptr, "Unknown13"}, | ||
| 254 | }; | ||
| 255 | // clang-format on | ||
| 256 | |||
| 257 | RegisterHandlers(functions); | ||
| 258 | } | ||
| 259 | }; | ||
| 260 | |||
| 261 | class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> { | ||
| 262 | public: | ||
| 263 | explicit IBtmSystemCore(Core::System& system_) : ServiceFramework{system_, "IBtmSystemCore"} { | ||
| 264 | // clang-format off | ||
| 265 | static const FunctionInfo functions[] = { | ||
| 266 | {0, &IBtmSystemCore::StartGamepadPairing, "StartGamepadPairing"}, | ||
| 267 | {1, &IBtmSystemCore::CancelGamepadPairing, "CancelGamepadPairing"}, | ||
| 268 | {2, nullptr, "ClearGamepadPairingDatabase"}, | ||
| 269 | {3, nullptr, "GetPairedGamepadCount"}, | ||
| 270 | {4, nullptr, "EnableRadio"}, | ||
| 271 | {5, nullptr, "DisableRadio"}, | ||
| 272 | {6, &IBtmSystemCore::IsRadioEnabled, "IsRadioEnabled"}, | ||
| 273 | {7, nullptr, "AcquireRadioEvent"}, | ||
| 274 | {8, nullptr, "AcquireGamepadPairingEvent"}, | ||
| 275 | {9, nullptr, "IsGamepadPairingStarted"}, | ||
| 276 | {10, nullptr, "StartAudioDeviceDiscovery"}, | ||
| 277 | {11, nullptr, "StopAudioDeviceDiscovery"}, | ||
| 278 | {12, nullptr, "IsDiscoveryingAudioDevice"}, | ||
| 279 | {13, nullptr, "GetDiscoveredAudioDevice"}, | ||
| 280 | {14, nullptr, "AcquireAudioDeviceConnectionEvent"}, | ||
| 281 | {15, nullptr, "ConnectAudioDevice"}, | ||
| 282 | {16, nullptr, "IsConnectingAudioDevice"}, | ||
| 283 | {17, &IBtmSystemCore::GetConnectedAudioDevices, "GetConnectedAudioDevices"}, | ||
| 284 | {18, nullptr, "DisconnectAudioDevice"}, | ||
| 285 | {19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"}, | ||
| 286 | {20, &IBtmSystemCore::GetPairedAudioDevices, "GetPairedAudioDevices"}, | ||
| 287 | {21, nullptr, "RemoveAudioDevicePairing"}, | ||
| 288 | {22, &IBtmSystemCore::RequestAudioDeviceConnectionRejection, "RequestAudioDeviceConnectionRejection"}, | ||
| 289 | {23, &IBtmSystemCore::CancelAudioDeviceConnectionRejection, "CancelAudioDeviceConnectionRejection"} | ||
| 290 | }; | ||
| 291 | // clang-format on | ||
| 292 | |||
| 293 | RegisterHandlers(functions); | ||
| 294 | } | ||
| 295 | |||
| 296 | private: | ||
| 297 | void IsRadioEnabled(HLERequestContext& ctx) { | ||
| 298 | LOG_DEBUG(Service_BTM, "(STUBBED) called"); // Spams a lot when controller applet is running | ||
| 299 | |||
| 300 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 301 | rb.Push(ResultSuccess); | ||
| 302 | rb.Push(true); | ||
| 303 | } | ||
| 304 | |||
| 305 | void StartGamepadPairing(HLERequestContext& ctx) { | ||
| 306 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 307 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 308 | rb.Push(ResultSuccess); | ||
| 309 | } | ||
| 310 | |||
| 311 | void CancelGamepadPairing(HLERequestContext& ctx) { | ||
| 312 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 313 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 314 | rb.Push(ResultSuccess); | ||
| 315 | } | ||
| 316 | |||
| 317 | void CancelAudioDeviceConnectionRejection(HLERequestContext& ctx) { | ||
| 318 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 319 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 320 | rb.Push(ResultSuccess); | ||
| 321 | } | ||
| 322 | |||
| 323 | void GetConnectedAudioDevices(HLERequestContext& ctx) { | ||
| 324 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 325 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 326 | rb.Push(ResultSuccess); | ||
| 327 | rb.Push<u32>(0); | ||
| 328 | } | ||
| 329 | |||
| 330 | void GetPairedAudioDevices(HLERequestContext& ctx) { | ||
| 331 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 332 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 333 | rb.Push(ResultSuccess); | ||
| 334 | rb.Push<u32>(0); | ||
| 335 | } | ||
| 336 | |||
| 337 | void RequestAudioDeviceConnectionRejection(HLERequestContext& ctx) { | ||
| 338 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 339 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 340 | rb.Push(ResultSuccess); | ||
| 341 | } | ||
| 342 | }; | ||
| 343 | |||
| 344 | class BTM_SYS final : public ServiceFramework<BTM_SYS> { | ||
| 345 | public: | ||
| 346 | explicit BTM_SYS(Core::System& system_) : ServiceFramework{system_, "btm:sys"} { | ||
| 347 | // clang-format off | ||
| 348 | static const FunctionInfo functions[] = { | ||
| 349 | {0, &BTM_SYS::GetCore, "GetCore"}, | ||
| 350 | }; | ||
| 351 | // clang-format on | ||
| 352 | |||
| 353 | RegisterHandlers(functions); | ||
| 354 | } | ||
| 355 | |||
| 356 | private: | ||
| 357 | void GetCore(HLERequestContext& ctx) { | ||
| 358 | LOG_WARNING(Service_BTM, "called"); | ||
| 359 | |||
| 360 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 361 | rb.Push(ResultSuccess); | ||
| 362 | rb.PushIpcInterface<IBtmSystemCore>(system); | ||
| 363 | } | ||
| 364 | }; | ||
| 365 | |||
| 366 | void LoopProcess(Core::System& system) { | 112 | void LoopProcess(Core::System& system) { |
| 367 | auto server_manager = std::make_unique<ServerManager>(system); | 113 | auto server_manager = std::make_unique<ServerManager>(system); |
| 368 | 114 | ||
| 369 | server_manager->RegisterNamedService("btm", std::make_shared<BTM>(system)); | 115 | server_manager->RegisterNamedService("btm", std::make_shared<IBtm>(system)); |
| 370 | server_manager->RegisterNamedService("btm:dbg", std::make_shared<BTM_DBG>(system)); | 116 | server_manager->RegisterNamedService("btm:dbg", std::make_shared<IBtmDebug>(system)); |
| 371 | server_manager->RegisterNamedService("btm:sys", std::make_shared<BTM_SYS>(system)); | 117 | server_manager->RegisterNamedService("btm:sys", std::make_shared<IBtmSystem>(system)); |
| 372 | server_manager->RegisterNamedService("btm:u", std::make_shared<BTM_USR>(system)); | 118 | server_manager->RegisterNamedService("btm:u", std::make_shared<IBtmUser>(system)); |
| 373 | ServerManager::RunServer(std::move(server_manager)); | 119 | ServerManager::RunServer(std::move(server_manager)); |
| 374 | } | 120 | } |
| 375 | 121 | ||
diff --git a/src/core/hle/service/btm/btm.h b/src/core/hle/service/btm/btm.h index a99b34364..0bf77d053 100644 --- a/src/core/hle/service/btm/btm.h +++ b/src/core/hle/service/btm/btm.h | |||
| @@ -3,10 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | namespace Service::SM { | ||
| 7 | class ServiceManager; | ||
| 8 | } | ||
| 9 | |||
| 10 | namespace Core { | 6 | namespace Core { |
| 11 | class System; | 7 | class System; |
| 12 | }; | 8 | }; |
diff --git a/src/core/hle/service/btm/btm_debug.cpp b/src/core/hle/service/btm/btm_debug.cpp new file mode 100644 index 000000000..4d61d2641 --- /dev/null +++ b/src/core/hle/service/btm/btm_debug.cpp | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/btm/btm_debug.h" | ||
| 5 | |||
| 6 | namespace Service::BTM { | ||
| 7 | |||
| 8 | IBtmDebug::IBtmDebug(Core::System& system_) : ServiceFramework{system_, "btm:dbg"} { | ||
| 9 | // clang-format off | ||
| 10 | static const FunctionInfo functions[] = { | ||
| 11 | {0, nullptr, "AcquireDiscoveryEvent"}, | ||
| 12 | {1, nullptr, "StartDiscovery"}, | ||
| 13 | {2, nullptr, "CancelDiscovery"}, | ||
| 14 | {3, nullptr, "GetDeviceProperty"}, | ||
| 15 | {4, nullptr, "CreateBond"}, | ||
| 16 | {5, nullptr, "CancelBond"}, | ||
| 17 | {6, nullptr, "SetTsiMode"}, | ||
| 18 | {7, nullptr, "GeneralTest"}, | ||
| 19 | {8, nullptr, "HidConnect"}, | ||
| 20 | {9, nullptr, "GeneralGet"}, | ||
| 21 | {10, nullptr, "GetGattClientDisconnectionReason"}, | ||
| 22 | {11, nullptr, "GetBleConnectionParameter"}, | ||
| 23 | {12, nullptr, "GetBleConnectionParameterRequest"}, | ||
| 24 | {13, nullptr, "Unknown13"}, | ||
| 25 | }; | ||
| 26 | // clang-format on | ||
| 27 | |||
| 28 | RegisterHandlers(functions); | ||
| 29 | } | ||
| 30 | |||
| 31 | IBtmDebug::~IBtmDebug() = default; | ||
| 32 | |||
| 33 | } // namespace Service::BTM | ||
diff --git a/src/core/hle/service/btm/btm_debug.h b/src/core/hle/service/btm/btm_debug.h new file mode 100644 index 000000000..bf4f7e14f --- /dev/null +++ b/src/core/hle/service/btm/btm_debug.h | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Core { | ||
| 10 | class System; | ||
| 11 | } | ||
| 12 | |||
| 13 | namespace Service::BTM { | ||
| 14 | |||
| 15 | class IBtmDebug final : public ServiceFramework<IBtmDebug> { | ||
| 16 | public: | ||
| 17 | explicit IBtmDebug(Core::System& system_); | ||
| 18 | ~IBtmDebug() override; | ||
| 19 | }; | ||
| 20 | |||
| 21 | } // namespace Service::BTM | ||
diff --git a/src/core/hle/service/btm/btm_system.cpp b/src/core/hle/service/btm/btm_system.cpp new file mode 100644 index 000000000..99718a7b0 --- /dev/null +++ b/src/core/hle/service/btm/btm_system.cpp | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "common/logging/log.h" | ||
| 5 | #include "core/hle/service/btm/btm_system.h" | ||
| 6 | #include "core/hle/service/btm/btm_system_core.h" | ||
| 7 | #include "core/hle/service/cmif_serialization.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | |||
| 10 | namespace Service::BTM { | ||
| 11 | |||
| 12 | IBtmSystem::IBtmSystem(Core::System& system_) : ServiceFramework{system_, "btm:sys"} { | ||
| 13 | // clang-format off | ||
| 14 | static const FunctionInfo functions[] = { | ||
| 15 | {0, C<&IBtmSystem::GetCore>, "GetCore"}, | ||
| 16 | }; | ||
| 17 | // clang-format on | ||
| 18 | |||
| 19 | RegisterHandlers(functions); | ||
| 20 | } | ||
| 21 | |||
| 22 | IBtmSystem::~IBtmSystem() = default; | ||
| 23 | |||
| 24 | Result IBtmSystem::GetCore(OutInterface<IBtmSystemCore> out_interface) { | ||
| 25 | LOG_WARNING(Service_BTM, "called"); | ||
| 26 | |||
| 27 | *out_interface = std::make_shared<IBtmSystemCore>(system); | ||
| 28 | R_SUCCEED(); | ||
| 29 | } | ||
| 30 | |||
| 31 | } // namespace Service::BTM | ||
diff --git a/src/core/hle/service/btm/btm_system.h b/src/core/hle/service/btm/btm_system.h new file mode 100644 index 000000000..fe1c6dbd7 --- /dev/null +++ b/src/core/hle/service/btm/btm_system.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Core { | ||
| 10 | class System; | ||
| 11 | } | ||
| 12 | |||
| 13 | namespace Service::BTM { | ||
| 14 | class IBtmSystemCore; | ||
| 15 | |||
| 16 | class IBtmSystem final : public ServiceFramework<IBtmSystem> { | ||
| 17 | public: | ||
| 18 | explicit IBtmSystem(Core::System& system_); | ||
| 19 | ~IBtmSystem() override; | ||
| 20 | |||
| 21 | private: | ||
| 22 | Result GetCore(OutInterface<IBtmSystemCore> out_interface); | ||
| 23 | }; | ||
| 24 | |||
| 25 | } // namespace Service::BTM | ||
diff --git a/src/core/hle/service/btm/btm_system_core.cpp b/src/core/hle/service/btm/btm_system_core.cpp new file mode 100644 index 000000000..4bc8a9e8b --- /dev/null +++ b/src/core/hle/service/btm/btm_system_core.cpp | |||
| @@ -0,0 +1,127 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "common/logging/log.h" | ||
| 5 | #include "core/hle/service/btm/btm_system_core.h" | ||
| 6 | #include "core/hle/service/cmif_serialization.h" | ||
| 7 | #include "core/hle/service/set/system_settings_server.h" | ||
| 8 | #include "core/hle/service/sm/sm.h" | ||
| 9 | |||
| 10 | namespace Service::BTM { | ||
| 11 | |||
| 12 | IBtmSystemCore::IBtmSystemCore(Core::System& system_) | ||
| 13 | : ServiceFramework{system_, "IBtmSystemCore"}, service_context{system_, "IBtmSystemCore"} { | ||
| 14 | // clang-format off | ||
| 15 | static const FunctionInfo functions[] = { | ||
| 16 | {0, C<&IBtmSystemCore::StartGamepadPairing>, "StartGamepadPairing"}, | ||
| 17 | {1, C<&IBtmSystemCore::CancelGamepadPairing>, "CancelGamepadPairing"}, | ||
| 18 | {2, nullptr, "ClearGamepadPairingDatabase"}, | ||
| 19 | {3, nullptr, "GetPairedGamepadCount"}, | ||
| 20 | {4, C<&IBtmSystemCore::EnableRadio>, "EnableRadio"}, | ||
| 21 | {5, C<&IBtmSystemCore::DisableRadio>, "DisableRadio"}, | ||
| 22 | {6, C<&IBtmSystemCore::IsRadioEnabled>, "IsRadioEnabled"}, | ||
| 23 | {7, C<&IBtmSystemCore::AcquireRadioEvent>, "AcquireRadioEvent"}, | ||
| 24 | {8, nullptr, "AcquireGamepadPairingEvent"}, | ||
| 25 | {9, nullptr, "IsGamepadPairingStarted"}, | ||
| 26 | {10, nullptr, "StartAudioDeviceDiscovery"}, | ||
| 27 | {11, nullptr, "StopAudioDeviceDiscovery"}, | ||
| 28 | {12, nullptr, "IsDiscoveryingAudioDevice"}, | ||
| 29 | {13, nullptr, "GetDiscoveredAudioDevice"}, | ||
| 30 | {14, C<&IBtmSystemCore::AcquireAudioDeviceConnectionEvent>, "AcquireAudioDeviceConnectionEvent"}, | ||
| 31 | {15, nullptr, "ConnectAudioDevice"}, | ||
| 32 | {16, nullptr, "IsConnectingAudioDevice"}, | ||
| 33 | {17, C<&IBtmSystemCore::GetConnectedAudioDevices>, "GetConnectedAudioDevices"}, | ||
| 34 | {18, nullptr, "DisconnectAudioDevice"}, | ||
| 35 | {19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"}, | ||
| 36 | {20, C<&IBtmSystemCore::GetPairedAudioDevices>, "GetPairedAudioDevices"}, | ||
| 37 | {21, nullptr, "RemoveAudioDevicePairing"}, | ||
| 38 | {22, C<&IBtmSystemCore::RequestAudioDeviceConnectionRejection>, "RequestAudioDeviceConnectionRejection"}, | ||
| 39 | {23, C<&IBtmSystemCore::CancelAudioDeviceConnectionRejection>, "CancelAudioDeviceConnectionRejection"} | ||
| 40 | }; | ||
| 41 | // clang-format on | ||
| 42 | |||
| 43 | RegisterHandlers(functions); | ||
| 44 | radio_event = service_context.CreateEvent("IBtmSystemCore::RadioEvent"); | ||
| 45 | audio_device_connection_event = | ||
| 46 | service_context.CreateEvent("IBtmSystemCore::AudioDeviceConnectionEvent"); | ||
| 47 | |||
| 48 | m_set_sys = | ||
| 49 | system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); | ||
| 50 | } | ||
| 51 | |||
| 52 | IBtmSystemCore::~IBtmSystemCore() { | ||
| 53 | service_context.CloseEvent(radio_event); | ||
| 54 | service_context.CloseEvent(audio_device_connection_event); | ||
| 55 | } | ||
| 56 | |||
| 57 | Result IBtmSystemCore::StartGamepadPairing() { | ||
| 58 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 59 | R_SUCCEED(); | ||
| 60 | } | ||
| 61 | |||
| 62 | Result IBtmSystemCore::CancelGamepadPairing() { | ||
| 63 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 64 | R_SUCCEED(); | ||
| 65 | } | ||
| 66 | |||
| 67 | Result IBtmSystemCore::EnableRadio() { | ||
| 68 | LOG_DEBUG(Service_BTM, "called"); | ||
| 69 | |||
| 70 | R_RETURN(m_set_sys->SetBluetoothEnableFlag(true)); | ||
| 71 | } | ||
| 72 | Result IBtmSystemCore::DisableRadio() { | ||
| 73 | LOG_DEBUG(Service_BTM, "called"); | ||
| 74 | |||
| 75 | R_RETURN(m_set_sys->SetBluetoothEnableFlag(false)); | ||
| 76 | } | ||
| 77 | |||
| 78 | Result IBtmSystemCore::IsRadioEnabled(Out<bool> out_is_enabled) { | ||
| 79 | LOG_DEBUG(Service_BTM, "called"); | ||
| 80 | |||
| 81 | R_RETURN(m_set_sys->GetBluetoothEnableFlag(out_is_enabled)); | ||
| 82 | } | ||
| 83 | |||
| 84 | Result IBtmSystemCore::AcquireRadioEvent(Out<bool> out_is_valid, | ||
| 85 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 86 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 87 | |||
| 88 | *out_is_valid = true; | ||
| 89 | *out_event = &radio_event->GetReadableEvent(); | ||
| 90 | R_SUCCEED(); | ||
| 91 | } | ||
| 92 | |||
| 93 | Result IBtmSystemCore::AcquireAudioDeviceConnectionEvent( | ||
| 94 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 95 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 96 | |||
| 97 | *out_event = &audio_device_connection_event->GetReadableEvent(); | ||
| 98 | R_SUCCEED(); | ||
| 99 | } | ||
| 100 | |||
| 101 | Result IBtmSystemCore::GetConnectedAudioDevices( | ||
| 102 | Out<s32> out_count, OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices) { | ||
| 103 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 104 | |||
| 105 | *out_count = 0; | ||
| 106 | R_SUCCEED(); | ||
| 107 | } | ||
| 108 | |||
| 109 | Result IBtmSystemCore::GetPairedAudioDevices( | ||
| 110 | Out<s32> out_count, OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices) { | ||
| 111 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 112 | |||
| 113 | *out_count = 0; | ||
| 114 | R_SUCCEED(); | ||
| 115 | } | ||
| 116 | |||
| 117 | Result IBtmSystemCore::RequestAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid) { | ||
| 118 | LOG_WARNING(Service_BTM, "(STUBBED) called, applet_resource_user_id={}", aruid.pid); | ||
| 119 | R_SUCCEED(); | ||
| 120 | } | ||
| 121 | |||
| 122 | Result IBtmSystemCore::CancelAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid) { | ||
| 123 | LOG_WARNING(Service_BTM, "(STUBBED) called, applet_resource_user_id={}", aruid.pid); | ||
| 124 | R_SUCCEED(); | ||
| 125 | } | ||
| 126 | |||
| 127 | } // namespace Service::BTM | ||
diff --git a/src/core/hle/service/btm/btm_system_core.h b/src/core/hle/service/btm/btm_system_core.h new file mode 100644 index 000000000..06498b21e --- /dev/null +++ b/src/core/hle/service/btm/btm_system_core.h | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/kernel_helpers.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | |||
| 10 | namespace Kernel { | ||
| 11 | class KEvent; | ||
| 12 | class KReadableEvent; | ||
| 13 | } // namespace Kernel | ||
| 14 | |||
| 15 | namespace Core { | ||
| 16 | class System; | ||
| 17 | } | ||
| 18 | |||
| 19 | namespace Service::Set { | ||
| 20 | class ISystemSettingsServer; | ||
| 21 | } | ||
| 22 | |||
| 23 | namespace Service::BTM { | ||
| 24 | |||
| 25 | class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> { | ||
| 26 | public: | ||
| 27 | explicit IBtmSystemCore(Core::System& system_); | ||
| 28 | ~IBtmSystemCore() override; | ||
| 29 | |||
| 30 | private: | ||
| 31 | Result StartGamepadPairing(); | ||
| 32 | Result CancelGamepadPairing(); | ||
| 33 | Result EnableRadio(); | ||
| 34 | Result DisableRadio(); | ||
| 35 | Result IsRadioEnabled(Out<bool> out_is_enabled); | ||
| 36 | |||
| 37 | Result AcquireRadioEvent(Out<bool> out_is_valid, | ||
| 38 | OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 39 | |||
| 40 | Result AcquireAudioDeviceConnectionEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 41 | |||
| 42 | Result GetConnectedAudioDevices( | ||
| 43 | Out<s32> out_count, | ||
| 44 | OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices); | ||
| 45 | |||
| 46 | Result GetPairedAudioDevices( | ||
| 47 | Out<s32> out_count, | ||
| 48 | OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices); | ||
| 49 | |||
| 50 | Result RequestAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid); | ||
| 51 | Result CancelAudioDeviceConnectionRejection(ClientAppletResourceUserId aruid); | ||
| 52 | |||
| 53 | KernelHelpers::ServiceContext service_context; | ||
| 54 | |||
| 55 | Kernel::KEvent* radio_event; | ||
| 56 | Kernel::KEvent* audio_device_connection_event; | ||
| 57 | std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; | ||
| 58 | }; | ||
| 59 | |||
| 60 | } // namespace Service::BTM | ||
diff --git a/src/core/hle/service/btm/btm_user.cpp b/src/core/hle/service/btm/btm_user.cpp new file mode 100644 index 000000000..d2e228f8d --- /dev/null +++ b/src/core/hle/service/btm/btm_user.cpp | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include "common/logging/log.h" | ||
| 5 | #include "core/hle/service/btm/btm_user.h" | ||
| 6 | #include "core/hle/service/btm/btm_user_core.h" | ||
| 7 | #include "core/hle/service/cmif_serialization.h" | ||
| 8 | |||
| 9 | namespace Service::BTM { | ||
| 10 | |||
| 11 | IBtmUser::IBtmUser(Core::System& system_) : ServiceFramework{system_, "btm:u"} { | ||
| 12 | // clang-format off | ||
| 13 | static const FunctionInfo functions[] = { | ||
| 14 | {0, C<&IBtmUser::GetCore>, "GetCore"}, | ||
| 15 | }; | ||
| 16 | // clang-format on | ||
| 17 | |||
| 18 | RegisterHandlers(functions); | ||
| 19 | } | ||
| 20 | |||
| 21 | IBtmUser::~IBtmUser() = default; | ||
| 22 | |||
| 23 | Result IBtmUser::GetCore(OutInterface<IBtmUserCore> out_interface) { | ||
| 24 | LOG_WARNING(Service_BTM, "called"); | ||
| 25 | |||
| 26 | *out_interface = std::make_shared<IBtmUserCore>(system); | ||
| 27 | R_SUCCEED(); | ||
| 28 | } | ||
| 29 | |||
| 30 | } // namespace Service::BTM | ||
diff --git a/src/core/hle/service/btm/btm_user.h b/src/core/hle/service/btm/btm_user.h new file mode 100644 index 000000000..d9ee5db45 --- /dev/null +++ b/src/core/hle/service/btm/btm_user.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Core { | ||
| 10 | class System; | ||
| 11 | } | ||
| 12 | |||
| 13 | namespace Service::BTM { | ||
| 14 | class IBtmUserCore; | ||
| 15 | |||
| 16 | class IBtmUser final : public ServiceFramework<IBtmUser> { | ||
| 17 | public: | ||
| 18 | explicit IBtmUser(Core::System& system_); | ||
| 19 | ~IBtmUser() override; | ||
| 20 | |||
| 21 | private: | ||
| 22 | Result GetCore(OutInterface<IBtmUserCore> out_interface); | ||
| 23 | }; | ||
| 24 | |||
| 25 | } // namespace Service::BTM | ||
diff --git a/src/core/hle/service/btm/btm_user_core.cpp b/src/core/hle/service/btm/btm_user_core.cpp new file mode 100644 index 000000000..6f9fa589b --- /dev/null +++ b/src/core/hle/service/btm/btm_user_core.cpp | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include <memory> | ||
| 5 | |||
| 6 | #include "common/logging/log.h" | ||
| 7 | #include "core/core.h" | ||
| 8 | #include "core/hle/kernel/k_event.h" | ||
| 9 | #include "core/hle/service/btm/btm_user_core.h" | ||
| 10 | #include "core/hle/service/cmif_serialization.h" | ||
| 11 | |||
| 12 | namespace Service::BTM { | ||
| 13 | |||
| 14 | IBtmUserCore::IBtmUserCore(Core::System& system_) | ||
| 15 | : ServiceFramework{system_, "IBtmUserCore"}, service_context{system_, "IBtmUserCore"} { | ||
| 16 | // clang-format off | ||
| 17 | static const FunctionInfo functions[] = { | ||
| 18 | {0, C<&IBtmUserCore::AcquireBleScanEvent>, "AcquireBleScanEvent"}, | ||
| 19 | {1, nullptr, "GetBleScanFilterParameter"}, | ||
| 20 | {2, nullptr, "GetBleScanFilterParameter2"}, | ||
| 21 | {3, nullptr, "StartBleScanForGeneral"}, | ||
| 22 | {4, nullptr, "StopBleScanForGeneral"}, | ||
| 23 | {5, nullptr, "GetBleScanResultsForGeneral"}, | ||
| 24 | {6, nullptr, "StartBleScanForPaired"}, | ||
| 25 | {7, nullptr, "StopBleScanForPaired"}, | ||
| 26 | {8, nullptr, "StartBleScanForSmartDevice"}, | ||
| 27 | {9, nullptr, "StopBleScanForSmartDevice"}, | ||
| 28 | {10, nullptr, "GetBleScanResultsForSmartDevice"}, | ||
| 29 | {17, C<&IBtmUserCore::AcquireBleConnectionEvent>, "AcquireBleConnectionEvent"}, | ||
| 30 | {18, nullptr, "BleConnect"}, | ||
| 31 | {19, nullptr, "BleDisconnect"}, | ||
| 32 | {20, nullptr, "BleGetConnectionState"}, | ||
| 33 | {21, nullptr, "AcquireBlePairingEvent"}, | ||
| 34 | {22, nullptr, "BlePairDevice"}, | ||
| 35 | {23, nullptr, "BleUnPairDevice"}, | ||
| 36 | {24, nullptr, "BleUnPairDevice2"}, | ||
| 37 | {25, nullptr, "BleGetPairedDevices"}, | ||
| 38 | {26, C<&IBtmUserCore::AcquireBleServiceDiscoveryEvent>, "AcquireBleServiceDiscoveryEvent"}, | ||
| 39 | {27, nullptr, "GetGattServices"}, | ||
| 40 | {28, nullptr, "GetGattService"}, | ||
| 41 | {29, nullptr, "GetGattIncludedServices"}, | ||
| 42 | {30, nullptr, "GetBelongingGattService"}, | ||
| 43 | {31, nullptr, "GetGattCharacteristics"}, | ||
| 44 | {32, nullptr, "GetGattDescriptors"}, | ||
| 45 | {33, C<&IBtmUserCore::AcquireBleMtuConfigEvent>, "AcquireBleMtuConfigEvent"}, | ||
| 46 | {34, nullptr, "ConfigureBleMtu"}, | ||
| 47 | {35, nullptr, "GetBleMtu"}, | ||
| 48 | {36, nullptr, "RegisterBleGattDataPath"}, | ||
| 49 | {37, nullptr, "UnregisterBleGattDataPath"}, | ||
| 50 | }; | ||
| 51 | // clang-format on | ||
| 52 | RegisterHandlers(functions); | ||
| 53 | |||
| 54 | scan_event = service_context.CreateEvent("IBtmUserCore:ScanEvent"); | ||
| 55 | connection_event = service_context.CreateEvent("IBtmUserCore:ConnectionEvent"); | ||
| 56 | service_discovery_event = service_context.CreateEvent("IBtmUserCore:DiscoveryEvent"); | ||
| 57 | config_event = service_context.CreateEvent("IBtmUserCore:ConfigEvent"); | ||
| 58 | } | ||
| 59 | |||
| 60 | IBtmUserCore::~IBtmUserCore() { | ||
| 61 | service_context.CloseEvent(scan_event); | ||
| 62 | service_context.CloseEvent(connection_event); | ||
| 63 | service_context.CloseEvent(service_discovery_event); | ||
| 64 | service_context.CloseEvent(config_event); | ||
| 65 | } | ||
| 66 | |||
| 67 | Result IBtmUserCore::AcquireBleScanEvent(Out<bool> out_is_valid, | ||
| 68 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 69 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 70 | |||
| 71 | *out_is_valid = true; | ||
| 72 | *out_event = &scan_event->GetReadableEvent(); | ||
| 73 | R_SUCCEED(); | ||
| 74 | } | ||
| 75 | |||
| 76 | Result IBtmUserCore::AcquireBleConnectionEvent(Out<bool> out_is_valid, | ||
| 77 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 78 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 79 | |||
| 80 | *out_is_valid = true; | ||
| 81 | *out_event = &connection_event->GetReadableEvent(); | ||
| 82 | R_SUCCEED(); | ||
| 83 | } | ||
| 84 | |||
| 85 | Result IBtmUserCore::AcquireBleServiceDiscoveryEvent( | ||
| 86 | Out<bool> out_is_valid, OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 87 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 88 | |||
| 89 | *out_is_valid = true; | ||
| 90 | *out_event = &service_discovery_event->GetReadableEvent(); | ||
| 91 | R_SUCCEED(); | ||
| 92 | } | ||
| 93 | |||
| 94 | Result IBtmUserCore::AcquireBleMtuConfigEvent(Out<bool> out_is_valid, | ||
| 95 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 96 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||
| 97 | |||
| 98 | *out_is_valid = true; | ||
| 99 | *out_event = &config_event->GetReadableEvent(); | ||
| 100 | R_SUCCEED(); | ||
| 101 | } | ||
| 102 | |||
| 103 | } // namespace Service::BTM | ||
diff --git a/src/core/hle/service/btm/btm_user_core.h b/src/core/hle/service/btm/btm_user_core.h new file mode 100644 index 000000000..dc0a22e81 --- /dev/null +++ b/src/core/hle/service/btm/btm_user_core.h | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/kernel_helpers.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | |||
| 10 | namespace Kernel { | ||
| 11 | class KEvent; | ||
| 12 | class KReadableEvent; | ||
| 13 | } // namespace Kernel | ||
| 14 | |||
| 15 | namespace Core { | ||
| 16 | class System; | ||
| 17 | } | ||
| 18 | |||
| 19 | namespace Service::BTM { | ||
| 20 | |||
| 21 | class IBtmUserCore final : public ServiceFramework<IBtmUserCore> { | ||
| 22 | public: | ||
| 23 | explicit IBtmUserCore(Core::System& system_); | ||
| 24 | ~IBtmUserCore() override; | ||
| 25 | |||
| 26 | private: | ||
| 27 | Result AcquireBleScanEvent(Out<bool> out_is_valid, | ||
| 28 | OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 29 | |||
| 30 | Result AcquireBleConnectionEvent(Out<bool> out_is_valid, | ||
| 31 | OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 32 | |||
| 33 | Result AcquireBleServiceDiscoveryEvent(Out<bool> out_is_valid, | ||
| 34 | OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 35 | |||
| 36 | Result AcquireBleMtuConfigEvent(Out<bool> out_is_valid, | ||
| 37 | OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 38 | |||
| 39 | KernelHelpers::ServiceContext service_context; | ||
| 40 | |||
| 41 | Kernel::KEvent* scan_event; | ||
| 42 | Kernel::KEvent* connection_event; | ||
| 43 | Kernel::KEvent* service_discovery_event; | ||
| 44 | Kernel::KEvent* config_event; | ||
| 45 | }; | ||
| 46 | |||
| 47 | } // namespace Service::BTM | ||
diff --git a/src/core/hle/service/glue/time/static.cpp b/src/core/hle/service/glue/time/static.cpp index ec9b0efb1..b801faef2 100644 --- a/src/core/hle/service/glue/time/static.cpp +++ b/src/core/hle/service/glue/time/static.cpp | |||
| @@ -142,16 +142,18 @@ Result StaticService::SetStandardSteadyClockInternalOffset(s64 offset_ns) { | |||
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | Result StaticService::GetStandardSteadyClockRtcValue(Out<s64> out_rtc_value) { | 144 | Result StaticService::GetStandardSteadyClockRtcValue(Out<s64> out_rtc_value) { |
| 145 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rtc_value={}", *out_rtc_value); }); | 145 | SCOPE_EXIT { |
| 146 | LOG_DEBUG(Service_Time, "called. out_rtc_value={}", *out_rtc_value); | ||
| 147 | }; | ||
| 146 | 148 | ||
| 147 | R_RETURN(m_standard_steady_clock_resource.GetRtcTimeInSeconds(*out_rtc_value)); | 149 | R_RETURN(m_standard_steady_clock_resource.GetRtcTimeInSeconds(*out_rtc_value)); |
| 148 | } | 150 | } |
| 149 | 151 | ||
| 150 | Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled( | 152 | Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled( |
| 151 | Out<bool> out_automatic_correction) { | 153 | Out<bool> out_automatic_correction) { |
| 152 | SCOPE_EXIT({ | 154 | SCOPE_EXIT { |
| 153 | LOG_DEBUG(Service_Time, "called. out_automatic_correction={}", *out_automatic_correction); | 155 | LOG_DEBUG(Service_Time, "called. out_automatic_correction={}", *out_automatic_correction); |
| 154 | }); | 156 | }; |
| 155 | 157 | ||
| 156 | R_RETURN(m_wrapped_service->IsStandardUserSystemClockAutomaticCorrectionEnabled( | 158 | R_RETURN(m_wrapped_service->IsStandardUserSystemClockAutomaticCorrectionEnabled( |
| 157 | out_automatic_correction)); | 159 | out_automatic_correction)); |
| @@ -166,21 +168,27 @@ Result StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled( | |||
| 166 | } | 168 | } |
| 167 | 169 | ||
| 168 | Result StaticService::GetStandardUserSystemClockInitialYear(Out<s32> out_year) { | 170 | Result StaticService::GetStandardUserSystemClockInitialYear(Out<s32> out_year) { |
| 169 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_year={}", *out_year); }); | 171 | SCOPE_EXIT { |
| 172 | LOG_DEBUG(Service_Time, "called. out_year={}", *out_year); | ||
| 173 | }; | ||
| 170 | 174 | ||
| 171 | R_RETURN(m_set_sys->GetSettingsItemValueImpl<s32>(*out_year, "time", | 175 | R_RETURN(m_set_sys->GetSettingsItemValueImpl<s32>(*out_year, "time", |
| 172 | "standard_user_clock_initial_year")); | 176 | "standard_user_clock_initial_year")); |
| 173 | } | 177 | } |
| 174 | 178 | ||
| 175 | Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(Out<bool> out_is_sufficient) { | 179 | Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(Out<bool> out_is_sufficient) { |
| 176 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_sufficient={}", *out_is_sufficient); }); | 180 | SCOPE_EXIT { |
| 181 | LOG_DEBUG(Service_Time, "called. out_is_sufficient={}", *out_is_sufficient); | ||
| 182 | }; | ||
| 177 | 183 | ||
| 178 | R_RETURN(m_wrapped_service->IsStandardNetworkSystemClockAccuracySufficient(out_is_sufficient)); | 184 | R_RETURN(m_wrapped_service->IsStandardNetworkSystemClockAccuracySufficient(out_is_sufficient)); |
| 179 | } | 185 | } |
| 180 | 186 | ||
| 181 | Result StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( | 187 | Result StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( |
| 182 | Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point) { | 188 | Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point) { |
| 183 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); }); | 189 | SCOPE_EXIT { |
| 190 | LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); | ||
| 191 | }; | ||
| 184 | 192 | ||
| 185 | R_RETURN(m_wrapped_service->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( | 193 | R_RETURN(m_wrapped_service->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( |
| 186 | out_time_point)); | 194 | out_time_point)); |
| @@ -188,15 +196,18 @@ Result StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( | |||
| 188 | 196 | ||
| 189 | Result StaticService::CalculateMonotonicSystemClockBaseTimePoint( | 197 | Result StaticService::CalculateMonotonicSystemClockBaseTimePoint( |
| 190 | Out<s64> out_time, const Service::PSC::Time::SystemClockContext& context) { | 198 | Out<s64> out_time, const Service::PSC::Time::SystemClockContext& context) { |
| 191 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. context={} out_time={}", context, *out_time); }); | 199 | SCOPE_EXIT { |
| 200 | LOG_DEBUG(Service_Time, "called. context={} out_time={}", context, *out_time); | ||
| 201 | }; | ||
| 192 | 202 | ||
| 193 | R_RETURN(m_wrapped_service->CalculateMonotonicSystemClockBaseTimePoint(out_time, context)); | 203 | R_RETURN(m_wrapped_service->CalculateMonotonicSystemClockBaseTimePoint(out_time, context)); |
| 194 | } | 204 | } |
| 195 | 205 | ||
| 196 | Result StaticService::GetClockSnapshot(OutClockSnapshot out_snapshot, | 206 | Result StaticService::GetClockSnapshot(OutClockSnapshot out_snapshot, |
| 197 | Service::PSC::Time::TimeType type) { | 207 | Service::PSC::Time::TimeType type) { |
| 198 | SCOPE_EXIT( | 208 | SCOPE_EXIT { |
| 199 | { LOG_DEBUG(Service_Time, "called. type={} out_snapshot={}", type, *out_snapshot); }); | 209 | LOG_DEBUG(Service_Time, "called. type={} out_snapshot={}", type, *out_snapshot); |
| 210 | }; | ||
| 200 | 211 | ||
| 201 | R_RETURN(m_wrapped_service->GetClockSnapshot(out_snapshot, type)); | 212 | R_RETURN(m_wrapped_service->GetClockSnapshot(out_snapshot, type)); |
| 202 | } | 213 | } |
| @@ -205,11 +216,11 @@ Result StaticService::GetClockSnapshotFromSystemClockContext( | |||
| 205 | Service::PSC::Time::TimeType type, OutClockSnapshot out_snapshot, | 216 | Service::PSC::Time::TimeType type, OutClockSnapshot out_snapshot, |
| 206 | const Service::PSC::Time::SystemClockContext& user_context, | 217 | const Service::PSC::Time::SystemClockContext& user_context, |
| 207 | const Service::PSC::Time::SystemClockContext& network_context) { | 218 | const Service::PSC::Time::SystemClockContext& network_context) { |
| 208 | SCOPE_EXIT({ | 219 | SCOPE_EXIT { |
| 209 | LOG_DEBUG(Service_Time, | 220 | LOG_DEBUG(Service_Time, |
| 210 | "called. type={} out_snapshot={} user_context={} network_context={}", type, | 221 | "called. type={} out_snapshot={} user_context={} network_context={}", type, |
| 211 | *out_snapshot, user_context, network_context); | 222 | *out_snapshot, user_context, network_context); |
| 212 | }); | 223 | }; |
| 213 | 224 | ||
| 214 | R_RETURN(m_wrapped_service->GetClockSnapshotFromSystemClockContext( | 225 | R_RETURN(m_wrapped_service->GetClockSnapshotFromSystemClockContext( |
| 215 | type, out_snapshot, user_context, network_context)); | 226 | type, out_snapshot, user_context, network_context)); |
| @@ -218,14 +229,18 @@ Result StaticService::GetClockSnapshotFromSystemClockContext( | |||
| 218 | Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(Out<s64> out_time, | 229 | Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(Out<s64> out_time, |
| 219 | InClockSnapshot a, | 230 | InClockSnapshot a, |
| 220 | InClockSnapshot b) { | 231 | InClockSnapshot b) { |
| 221 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); }); | 232 | SCOPE_EXIT { |
| 233 | LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); | ||
| 234 | }; | ||
| 222 | 235 | ||
| 223 | R_RETURN(m_wrapped_service->CalculateStandardUserSystemClockDifferenceByUser(out_time, a, b)); | 236 | R_RETURN(m_wrapped_service->CalculateStandardUserSystemClockDifferenceByUser(out_time, a, b)); |
| 224 | } | 237 | } |
| 225 | 238 | ||
| 226 | Result StaticService::CalculateSpanBetween(Out<s64> out_time, InClockSnapshot a, | 239 | Result StaticService::CalculateSpanBetween(Out<s64> out_time, InClockSnapshot a, |
| 227 | InClockSnapshot b) { | 240 | InClockSnapshot b) { |
| 228 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); }); | 241 | SCOPE_EXIT { |
| 242 | LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); | ||
| 243 | }; | ||
| 229 | 244 | ||
| 230 | R_RETURN(m_wrapped_service->CalculateSpanBetween(out_time, a, b)); | 245 | R_RETURN(m_wrapped_service->CalculateSpanBetween(out_time, a, b)); |
| 231 | } | 246 | } |
diff --git a/src/core/hle/service/glue/time/time_zone.cpp b/src/core/hle/service/glue/time/time_zone.cpp index 36f163419..f4d0c87d5 100644 --- a/src/core/hle/service/glue/time/time_zone.cpp +++ b/src/core/hle/service/glue/time/time_zone.cpp | |||
| @@ -57,7 +57,9 @@ TimeZoneService::~TimeZoneService() = default; | |||
| 57 | 57 | ||
| 58 | Result TimeZoneService::GetDeviceLocationName( | 58 | Result TimeZoneService::GetDeviceLocationName( |
| 59 | Out<Service::PSC::Time::LocationName> out_location_name) { | 59 | Out<Service::PSC::Time::LocationName> out_location_name) { |
| 60 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_location_name={}", *out_location_name); }); | 60 | SCOPE_EXIT { |
| 61 | LOG_DEBUG(Service_Time, "called. out_location_name={}", *out_location_name); | ||
| 62 | }; | ||
| 61 | 63 | ||
| 62 | R_RETURN(m_wrapped_service->GetDeviceLocationName(out_location_name)); | 64 | R_RETURN(m_wrapped_service->GetDeviceLocationName(out_location_name)); |
| 63 | } | 65 | } |
| @@ -94,7 +96,9 @@ Result TimeZoneService::SetDeviceLocationName( | |||
| 94 | } | 96 | } |
| 95 | 97 | ||
| 96 | Result TimeZoneService::GetTotalLocationNameCount(Out<u32> out_count) { | 98 | Result TimeZoneService::GetTotalLocationNameCount(Out<u32> out_count) { |
| 97 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_count={}", *out_count); }); | 99 | SCOPE_EXIT { |
| 100 | LOG_DEBUG(Service_Time, "called. out_count={}", *out_count); | ||
| 101 | }; | ||
| 98 | 102 | ||
| 99 | R_RETURN(m_wrapped_service->GetTotalLocationNameCount(out_count)); | 103 | R_RETURN(m_wrapped_service->GetTotalLocationNameCount(out_count)); |
| 100 | } | 104 | } |
| @@ -102,10 +106,10 @@ Result TimeZoneService::GetTotalLocationNameCount(Out<u32> out_count) { | |||
| 102 | Result TimeZoneService::LoadLocationNameList( | 106 | Result TimeZoneService::LoadLocationNameList( |
| 103 | Out<u32> out_count, | 107 | Out<u32> out_count, |
| 104 | OutArray<Service::PSC::Time::LocationName, BufferAttr_HipcMapAlias> out_names, u32 index) { | 108 | OutArray<Service::PSC::Time::LocationName, BufferAttr_HipcMapAlias> out_names, u32 index) { |
| 105 | SCOPE_EXIT({ | 109 | SCOPE_EXIT { |
| 106 | LOG_DEBUG(Service_Time, "called. index={} out_count={} out_names[0]={} out_names[1]={}", | 110 | LOG_DEBUG(Service_Time, "called. index={} out_count={} out_names[0]={} out_names[1]={}", |
| 107 | index, *out_count, out_names[0], out_names[1]); | 111 | index, *out_count, out_names[0], out_names[1]); |
| 108 | }); | 112 | }; |
| 109 | 113 | ||
| 110 | std::scoped_lock l{m_mutex}; | 114 | std::scoped_lock l{m_mutex}; |
| 111 | R_RETURN(GetTimeZoneLocationList(*out_count, out_names, out_names.size(), index)); | 115 | R_RETURN(GetTimeZoneLocationList(*out_count, out_names, out_names.size(), index)); |
| @@ -124,7 +128,9 @@ Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule, | |||
| 124 | 128 | ||
| 125 | Result TimeZoneService::GetTimeZoneRuleVersion( | 129 | Result TimeZoneService::GetTimeZoneRuleVersion( |
| 126 | Out<Service::PSC::Time::RuleVersion> out_rule_version) { | 130 | Out<Service::PSC::Time::RuleVersion> out_rule_version) { |
| 127 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rule_version={}", *out_rule_version); }); | 131 | SCOPE_EXIT { |
| 132 | LOG_DEBUG(Service_Time, "called. out_rule_version={}", *out_rule_version); | ||
| 133 | }; | ||
| 128 | 134 | ||
| 129 | R_RETURN(m_wrapped_service->GetTimeZoneRuleVersion(out_rule_version)); | 135 | R_RETURN(m_wrapped_service->GetTimeZoneRuleVersion(out_rule_version)); |
| 130 | } | 136 | } |
| @@ -132,10 +138,10 @@ Result TimeZoneService::GetTimeZoneRuleVersion( | |||
| 132 | Result TimeZoneService::GetDeviceLocationNameAndUpdatedTime( | 138 | Result TimeZoneService::GetDeviceLocationNameAndUpdatedTime( |
| 133 | Out<Service::PSC::Time::LocationName> location_name, | 139 | Out<Service::PSC::Time::LocationName> location_name, |
| 134 | Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point) { | 140 | Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point) { |
| 135 | SCOPE_EXIT({ | 141 | SCOPE_EXIT { |
| 136 | LOG_DEBUG(Service_Time, "called. location_name={} out_time_point={}", *location_name, | 142 | LOG_DEBUG(Service_Time, "called. location_name={} out_time_point={}", *location_name, |
| 137 | *out_time_point); | 143 | *out_time_point); |
| 138 | }); | 144 | }; |
| 139 | 145 | ||
| 140 | R_RETURN(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(location_name, out_time_point)); | 146 | R_RETURN(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(location_name, out_time_point)); |
| 141 | } | 147 | } |
| @@ -178,10 +184,10 @@ Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle( | |||
| 178 | Result TimeZoneService::ToCalendarTime( | 184 | Result TimeZoneService::ToCalendarTime( |
| 179 | Out<Service::PSC::Time::CalendarTime> out_calendar_time, | 185 | Out<Service::PSC::Time::CalendarTime> out_calendar_time, |
| 180 | Out<Service::PSC::Time::CalendarAdditionalInfo> out_additional_info, s64 time, InRule rule) { | 186 | Out<Service::PSC::Time::CalendarAdditionalInfo> out_additional_info, s64 time, InRule rule) { |
| 181 | SCOPE_EXIT({ | 187 | SCOPE_EXIT { |
| 182 | LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, | 188 | LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, |
| 183 | *out_calendar_time, *out_additional_info); | 189 | *out_calendar_time, *out_additional_info); |
| 184 | }); | 190 | }; |
| 185 | 191 | ||
| 186 | R_RETURN(m_wrapped_service->ToCalendarTime(out_calendar_time, out_additional_info, time, rule)); | 192 | R_RETURN(m_wrapped_service->ToCalendarTime(out_calendar_time, out_additional_info, time, rule)); |
| 187 | } | 193 | } |
| @@ -189,10 +195,10 @@ Result TimeZoneService::ToCalendarTime( | |||
| 189 | Result TimeZoneService::ToCalendarTimeWithMyRule( | 195 | Result TimeZoneService::ToCalendarTimeWithMyRule( |
| 190 | Out<Service::PSC::Time::CalendarTime> out_calendar_time, | 196 | Out<Service::PSC::Time::CalendarTime> out_calendar_time, |
| 191 | Out<Service::PSC::Time::CalendarAdditionalInfo> out_additional_info, s64 time) { | 197 | Out<Service::PSC::Time::CalendarAdditionalInfo> out_additional_info, s64 time) { |
| 192 | SCOPE_EXIT({ | 198 | SCOPE_EXIT { |
| 193 | LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, | 199 | LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, |
| 194 | *out_calendar_time, *out_additional_info); | 200 | *out_calendar_time, *out_additional_info); |
| 195 | }); | 201 | }; |
| 196 | 202 | ||
| 197 | R_RETURN( | 203 | R_RETURN( |
| 198 | m_wrapped_service->ToCalendarTimeWithMyRule(out_calendar_time, out_additional_info, time)); | 204 | m_wrapped_service->ToCalendarTimeWithMyRule(out_calendar_time, out_additional_info, time)); |
| @@ -202,11 +208,11 @@ Result TimeZoneService::ToPosixTime(Out<u32> out_count, | |||
| 202 | OutArray<s64, BufferAttr_HipcPointer> out_times, | 208 | OutArray<s64, BufferAttr_HipcPointer> out_times, |
| 203 | const Service::PSC::Time::CalendarTime& calendar_time, | 209 | const Service::PSC::Time::CalendarTime& calendar_time, |
| 204 | InRule rule) { | 210 | InRule rule) { |
| 205 | SCOPE_EXIT({ | 211 | SCOPE_EXIT { |
| 206 | LOG_DEBUG(Service_Time, | 212 | LOG_DEBUG(Service_Time, |
| 207 | "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={}", | 213 | "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={}", |
| 208 | calendar_time, *out_count, out_times[0], out_times[1]); | 214 | calendar_time, *out_count, out_times[0], out_times[1]); |
| 209 | }); | 215 | }; |
| 210 | 216 | ||
| 211 | R_RETURN(m_wrapped_service->ToPosixTime(out_count, out_times, calendar_time, rule)); | 217 | R_RETURN(m_wrapped_service->ToPosixTime(out_count, out_times, calendar_time, rule)); |
| 212 | } | 218 | } |
| @@ -214,11 +220,11 @@ Result TimeZoneService::ToPosixTime(Out<u32> out_count, | |||
| 214 | Result TimeZoneService::ToPosixTimeWithMyRule( | 220 | Result TimeZoneService::ToPosixTimeWithMyRule( |
| 215 | Out<u32> out_count, OutArray<s64, BufferAttr_HipcPointer> out_times, | 221 | Out<u32> out_count, OutArray<s64, BufferAttr_HipcPointer> out_times, |
| 216 | const Service::PSC::Time::CalendarTime& calendar_time) { | 222 | const Service::PSC::Time::CalendarTime& calendar_time) { |
| 217 | SCOPE_EXIT({ | 223 | SCOPE_EXIT { |
| 218 | LOG_DEBUG(Service_Time, | 224 | LOG_DEBUG(Service_Time, |
| 219 | "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={}", | 225 | "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={}", |
| 220 | calendar_time, *out_count, out_times[0], out_times[1]); | 226 | calendar_time, *out_count, out_times[0], out_times[1]); |
| 221 | }); | 227 | }; |
| 222 | 228 | ||
| 223 | R_RETURN(m_wrapped_service->ToPosixTimeWithMyRule(out_count, out_times, calendar_time)); | 229 | R_RETURN(m_wrapped_service->ToPosixTimeWithMyRule(out_count, out_times, calendar_time)); |
| 224 | } | 230 | } |
diff --git a/src/core/hle/service/ns/account_proxy_interface.cpp b/src/core/hle/service/ns/account_proxy_interface.cpp new file mode 100644 index 000000000..e5041af66 --- /dev/null +++ b/src/core/hle/service/ns/account_proxy_interface.cpp | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/ns/account_proxy_interface.h" | ||
| 5 | |||
| 6 | namespace Service::NS { | ||
| 7 | |||
| 8 | IAccountProxyInterface::IAccountProxyInterface(Core::System& system_) | ||
| 9 | : ServiceFramework{system_, "IAccountProxyInterface"} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, nullptr, "CreateUserAccount"}, | ||
| 13 | }; | ||
| 14 | // clang-format on | ||
| 15 | |||
| 16 | RegisterHandlers(functions); | ||
| 17 | } | ||
| 18 | |||
| 19 | IAccountProxyInterface::~IAccountProxyInterface() = default; | ||
| 20 | |||
| 21 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/account_proxy_interface.h b/src/core/hle/service/ns/account_proxy_interface.h new file mode 100644 index 000000000..e944d2a75 --- /dev/null +++ b/src/core/hle/service/ns/account_proxy_interface.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::NS { | ||
| 9 | |||
| 10 | class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> { | ||
| 11 | public: | ||
| 12 | explicit IAccountProxyInterface(Core::System& system_); | ||
| 13 | ~IAccountProxyInterface() override; | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/application_manager_interface.cpp b/src/core/hle/service/ns/application_manager_interface.cpp new file mode 100644 index 000000000..7a91727f9 --- /dev/null +++ b/src/core/hle/service/ns/application_manager_interface.cpp | |||
| @@ -0,0 +1,519 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/file_sys/nca_metadata.h" | ||
| 5 | #include "core/file_sys/registered_cache.h" | ||
| 6 | #include "core/hle/service/cmif_serialization.h" | ||
| 7 | #include "core/hle/service/filesystem/filesystem.h" | ||
| 8 | #include "core/hle/service/ns/application_manager_interface.h" | ||
| 9 | #include "core/hle/service/ns/content_management_interface.h" | ||
| 10 | #include "core/hle/service/ns/read_only_application_control_data_interface.h" | ||
| 11 | |||
| 12 | namespace Service::NS { | ||
| 13 | |||
| 14 | IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_) | ||
| 15 | : ServiceFramework{system_, "IApplicationManagerInterface"}, | ||
| 16 | service_context{system, "IApplicationManagerInterface"}, | ||
| 17 | record_update_system_event{service_context}, sd_card_mount_status_event{service_context}, | ||
| 18 | gamecard_update_detection_event{service_context}, | ||
| 19 | gamecard_mount_status_event{service_context}, gamecard_mount_failure_event{service_context} { | ||
| 20 | // clang-format off | ||
| 21 | static const FunctionInfo functions[] = { | ||
| 22 | {0, D<&IApplicationManagerInterface::ListApplicationRecord>, "ListApplicationRecord"}, | ||
| 23 | {1, nullptr, "GenerateApplicationRecordCount"}, | ||
| 24 | {2, D<&IApplicationManagerInterface::GetApplicationRecordUpdateSystemEvent>, "GetApplicationRecordUpdateSystemEvent"}, | ||
| 25 | {3, nullptr, "GetApplicationViewDeprecated"}, | ||
| 26 | {4, nullptr, "DeleteApplicationEntity"}, | ||
| 27 | {5, nullptr, "DeleteApplicationCompletely"}, | ||
| 28 | {6, nullptr, "IsAnyApplicationEntityRedundant"}, | ||
| 29 | {7, nullptr, "DeleteRedundantApplicationEntity"}, | ||
| 30 | {8, nullptr, "IsApplicationEntityMovable"}, | ||
| 31 | {9, nullptr, "MoveApplicationEntity"}, | ||
| 32 | {11, nullptr, "CalculateApplicationOccupiedSize"}, | ||
| 33 | {16, nullptr, "PushApplicationRecord"}, | ||
| 34 | {17, nullptr, "ListApplicationRecordContentMeta"}, | ||
| 35 | {19, nullptr, "LaunchApplicationOld"}, | ||
| 36 | {21, nullptr, "GetApplicationContentPath"}, | ||
| 37 | {22, nullptr, "TerminateApplication"}, | ||
| 38 | {23, nullptr, "ResolveApplicationContentPath"}, | ||
| 39 | {26, nullptr, "BeginInstallApplication"}, | ||
| 40 | {27, nullptr, "DeleteApplicationRecord"}, | ||
| 41 | {30, nullptr, "RequestApplicationUpdateInfo"}, | ||
| 42 | {31, nullptr, "Unknown31"}, | ||
| 43 | {32, nullptr, "CancelApplicationDownload"}, | ||
| 44 | {33, nullptr, "ResumeApplicationDownload"}, | ||
| 45 | {35, nullptr, "UpdateVersionList"}, | ||
| 46 | {36, nullptr, "PushLaunchVersion"}, | ||
| 47 | {37, nullptr, "ListRequiredVersion"}, | ||
| 48 | {38, D<&IApplicationManagerInterface::CheckApplicationLaunchVersion>, "CheckApplicationLaunchVersion"}, | ||
| 49 | {39, nullptr, "CheckApplicationLaunchRights"}, | ||
| 50 | {40, nullptr, "GetApplicationLogoData"}, | ||
| 51 | {41, nullptr, "CalculateApplicationDownloadRequiredSize"}, | ||
| 52 | {42, nullptr, "CleanupSdCard"}, | ||
| 53 | {43, D<&IApplicationManagerInterface::CheckSdCardMountStatus>, "CheckSdCardMountStatus"}, | ||
| 54 | {44, D<&IApplicationManagerInterface::GetSdCardMountStatusChangedEvent>, "GetSdCardMountStatusChangedEvent"}, | ||
| 55 | {45, nullptr, "GetGameCardAttachmentEvent"}, | ||
| 56 | {46, nullptr, "GetGameCardAttachmentInfo"}, | ||
| 57 | {47, nullptr, "GetTotalSpaceSize"}, | ||
| 58 | {48, D<&IApplicationManagerInterface::GetFreeSpaceSize>, "GetFreeSpaceSize"}, | ||
| 59 | {49, nullptr, "GetSdCardRemovedEvent"}, | ||
| 60 | {52, D<&IApplicationManagerInterface::GetGameCardUpdateDetectionEvent>, "GetGameCardUpdateDetectionEvent"}, | ||
| 61 | {53, nullptr, "DisableApplicationAutoDelete"}, | ||
| 62 | {54, nullptr, "EnableApplicationAutoDelete"}, | ||
| 63 | {55, D<&IApplicationManagerInterface::GetApplicationDesiredLanguage>, "GetApplicationDesiredLanguage"}, | ||
| 64 | {56, nullptr, "SetApplicationTerminateResult"}, | ||
| 65 | {57, nullptr, "ClearApplicationTerminateResult"}, | ||
| 66 | {58, nullptr, "GetLastSdCardMountUnexpectedResult"}, | ||
| 67 | {59, D<&IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode>, "ConvertApplicationLanguageToLanguageCode"}, | ||
| 68 | {60, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, | ||
| 69 | {61, nullptr, "GetBackgroundDownloadStressTaskInfo"}, | ||
| 70 | {62, nullptr, "GetGameCardStopper"}, | ||
| 71 | {63, nullptr, "IsSystemProgramInstalled"}, | ||
| 72 | {64, nullptr, "StartApplyDeltaTask"}, | ||
| 73 | {65, nullptr, "GetRequestServerStopper"}, | ||
| 74 | {66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"}, | ||
| 75 | {67, nullptr, "CancelApplicationApplyDelta"}, | ||
| 76 | {68, nullptr, "ResumeApplicationApplyDelta"}, | ||
| 77 | {69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"}, | ||
| 78 | {70, D<&IApplicationManagerInterface::ResumeAll>, "ResumeAll"}, | ||
| 79 | {71, D<&IApplicationManagerInterface::GetStorageSize>, "GetStorageSize"}, | ||
| 80 | {80, nullptr, "RequestDownloadApplication"}, | ||
| 81 | {81, nullptr, "RequestDownloadAddOnContent"}, | ||
| 82 | {82, nullptr, "DownloadApplication"}, | ||
| 83 | {83, nullptr, "CheckApplicationResumeRights"}, | ||
| 84 | {84, nullptr, "GetDynamicCommitEvent"}, | ||
| 85 | {85, nullptr, "RequestUpdateApplication2"}, | ||
| 86 | {86, nullptr, "EnableApplicationCrashReport"}, | ||
| 87 | {87, nullptr, "IsApplicationCrashReportEnabled"}, | ||
| 88 | {90, nullptr, "BoostSystemMemoryResourceLimit"}, | ||
| 89 | {91, nullptr, "DeprecatedLaunchApplication"}, | ||
| 90 | {92, nullptr, "GetRunningApplicationProgramId"}, | ||
| 91 | {93, nullptr, "GetMainApplicationProgramIndex"}, | ||
| 92 | {94, nullptr, "LaunchApplication"}, | ||
| 93 | {95, nullptr, "GetApplicationLaunchInfo"}, | ||
| 94 | {96, nullptr, "AcquireApplicationLaunchInfo"}, | ||
| 95 | {97, nullptr, "GetMainApplicationProgramIndexByApplicationLaunchInfo"}, | ||
| 96 | {98, nullptr, "EnableApplicationAllThreadDumpOnCrash"}, | ||
| 97 | {99, nullptr, "LaunchDevMenu"}, | ||
| 98 | {100, nullptr, "ResetToFactorySettings"}, | ||
| 99 | {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, | ||
| 100 | {102, nullptr, "ResetToFactorySettingsForRefurbishment"}, | ||
| 101 | {103, nullptr, "ResetToFactorySettingsWithPlatformRegion"}, | ||
| 102 | {104, nullptr, "ResetToFactorySettingsWithPlatformRegionAuthentication"}, | ||
| 103 | {105, nullptr, "RequestResetToFactorySettingsSecurely"}, | ||
| 104 | {106, nullptr, "RequestResetToFactorySettingsWithPlatformRegionAuthenticationSecurely"}, | ||
| 105 | {200, nullptr, "CalculateUserSaveDataStatistics"}, | ||
| 106 | {201, nullptr, "DeleteUserSaveDataAll"}, | ||
| 107 | {210, nullptr, "DeleteUserSystemSaveData"}, | ||
| 108 | {211, nullptr, "DeleteSaveData"}, | ||
| 109 | {220, nullptr, "UnregisterNetworkServiceAccount"}, | ||
| 110 | {221, nullptr, "UnregisterNetworkServiceAccountWithUserSaveDataDeletion"}, | ||
| 111 | {300, nullptr, "GetApplicationShellEvent"}, | ||
| 112 | {301, nullptr, "PopApplicationShellEventInfo"}, | ||
| 113 | {302, nullptr, "LaunchLibraryApplet"}, | ||
| 114 | {303, nullptr, "TerminateLibraryApplet"}, | ||
| 115 | {304, nullptr, "LaunchSystemApplet"}, | ||
| 116 | {305, nullptr, "TerminateSystemApplet"}, | ||
| 117 | {306, nullptr, "LaunchOverlayApplet"}, | ||
| 118 | {307, nullptr, "TerminateOverlayApplet"}, | ||
| 119 | {400, D<&IApplicationManagerInterface::GetApplicationControlData>, "GetApplicationControlData"}, | ||
| 120 | {401, nullptr, "InvalidateAllApplicationControlCache"}, | ||
| 121 | {402, nullptr, "RequestDownloadApplicationControlData"}, | ||
| 122 | {403, nullptr, "GetMaxApplicationControlCacheCount"}, | ||
| 123 | {404, nullptr, "InvalidateApplicationControlCache"}, | ||
| 124 | {405, nullptr, "ListApplicationControlCacheEntryInfo"}, | ||
| 125 | {406, nullptr, "GetApplicationControlProperty"}, | ||
| 126 | {407, nullptr, "ListApplicationTitle"}, | ||
| 127 | {408, nullptr, "ListApplicationIcon"}, | ||
| 128 | {502, nullptr, "RequestCheckGameCardRegistration"}, | ||
| 129 | {503, nullptr, "RequestGameCardRegistrationGoldPoint"}, | ||
| 130 | {504, nullptr, "RequestRegisterGameCard"}, | ||
| 131 | {505, D<&IApplicationManagerInterface::GetGameCardMountFailureEvent>, "GetGameCardMountFailureEvent"}, | ||
| 132 | {506, nullptr, "IsGameCardInserted"}, | ||
| 133 | {507, nullptr, "EnsureGameCardAccess"}, | ||
| 134 | {508, nullptr, "GetLastGameCardMountFailureResult"}, | ||
| 135 | {509, nullptr, "ListApplicationIdOnGameCard"}, | ||
| 136 | {510, nullptr, "GetGameCardPlatformRegion"}, | ||
| 137 | {600, nullptr, "CountApplicationContentMeta"}, | ||
| 138 | {601, nullptr, "ListApplicationContentMetaStatus"}, | ||
| 139 | {602, nullptr, "ListAvailableAddOnContent"}, | ||
| 140 | {603, nullptr, "GetOwnedApplicationContentMetaStatus"}, | ||
| 141 | {604, nullptr, "RegisterContentsExternalKey"}, | ||
| 142 | {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"}, | ||
| 143 | {606, nullptr, "GetContentMetaStorage"}, | ||
| 144 | {607, nullptr, "ListAvailableAddOnContent"}, | ||
| 145 | {609, nullptr, "ListAvailabilityAssuredAddOnContent"}, | ||
| 146 | {610, nullptr, "GetInstalledContentMetaStorage"}, | ||
| 147 | {611, nullptr, "PrepareAddOnContent"}, | ||
| 148 | {700, nullptr, "PushDownloadTaskList"}, | ||
| 149 | {701, nullptr, "ClearTaskStatusList"}, | ||
| 150 | {702, nullptr, "RequestDownloadTaskList"}, | ||
| 151 | {703, nullptr, "RequestEnsureDownloadTask"}, | ||
| 152 | {704, nullptr, "ListDownloadTaskStatus"}, | ||
| 153 | {705, nullptr, "RequestDownloadTaskListData"}, | ||
| 154 | {800, nullptr, "RequestVersionList"}, | ||
| 155 | {801, nullptr, "ListVersionList"}, | ||
| 156 | {802, nullptr, "RequestVersionListData"}, | ||
| 157 | {900, nullptr, "GetApplicationRecord"}, | ||
| 158 | {901, nullptr, "GetApplicationRecordProperty"}, | ||
| 159 | {902, nullptr, "EnableApplicationAutoUpdate"}, | ||
| 160 | {903, nullptr, "DisableApplicationAutoUpdate"}, | ||
| 161 | {904, nullptr, "TouchApplication"}, | ||
| 162 | {905, nullptr, "RequestApplicationUpdate"}, | ||
| 163 | {906, D<&IApplicationManagerInterface::IsApplicationUpdateRequested>, "IsApplicationUpdateRequested"}, | ||
| 164 | {907, nullptr, "WithdrawApplicationUpdateRequest"}, | ||
| 165 | {908, nullptr, "ListApplicationRecordInstalledContentMeta"}, | ||
| 166 | {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"}, | ||
| 167 | {910, nullptr, "HasApplicationRecord"}, | ||
| 168 | {911, nullptr, "SetPreInstalledApplication"}, | ||
| 169 | {912, nullptr, "ClearPreInstalledApplicationFlag"}, | ||
| 170 | {913, nullptr, "ListAllApplicationRecord"}, | ||
| 171 | {914, nullptr, "HideApplicationRecord"}, | ||
| 172 | {915, nullptr, "ShowApplicationRecord"}, | ||
| 173 | {916, nullptr, "IsApplicationAutoDeleteDisabled"}, | ||
| 174 | {1000, nullptr, "RequestVerifyApplicationDeprecated"}, | ||
| 175 | {1001, nullptr, "CorruptApplicationForDebug"}, | ||
| 176 | {1002, nullptr, "RequestVerifyAddOnContentsRights"}, | ||
| 177 | {1003, nullptr, "RequestVerifyApplication"}, | ||
| 178 | {1004, nullptr, "CorruptContentForDebug"}, | ||
| 179 | {1200, nullptr, "NeedsUpdateVulnerability"}, | ||
| 180 | {1300, D<&IApplicationManagerInterface::IsAnyApplicationEntityInstalled>, "IsAnyApplicationEntityInstalled"}, | ||
| 181 | {1301, nullptr, "DeleteApplicationContentEntities"}, | ||
| 182 | {1302, nullptr, "CleanupUnrecordedApplicationEntity"}, | ||
| 183 | {1303, nullptr, "CleanupAddOnContentsWithNoRights"}, | ||
| 184 | {1304, nullptr, "DeleteApplicationContentEntity"}, | ||
| 185 | {1305, nullptr, "TryDeleteRunningApplicationEntity"}, | ||
| 186 | {1306, nullptr, "TryDeleteRunningApplicationCompletely"}, | ||
| 187 | {1307, nullptr, "TryDeleteRunningApplicationContentEntities"}, | ||
| 188 | {1308, nullptr, "DeleteApplicationCompletelyForDebug"}, | ||
| 189 | {1309, nullptr, "CleanupUnavailableAddOnContents"}, | ||
| 190 | {1310, nullptr, "RequestMoveApplicationEntity"}, | ||
| 191 | {1311, nullptr, "EstimateSizeToMove"}, | ||
| 192 | {1312, nullptr, "HasMovableEntity"}, | ||
| 193 | {1313, nullptr, "CleanupOrphanContents"}, | ||
| 194 | {1314, nullptr, "CheckPreconditionSatisfiedToMove"}, | ||
| 195 | {1400, nullptr, "PrepareShutdown"}, | ||
| 196 | {1500, nullptr, "FormatSdCard"}, | ||
| 197 | {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"}, | ||
| 198 | {1502, nullptr, "GetLastSdCardFormatUnexpectedResult"}, | ||
| 199 | {1504, nullptr, "InsertSdCard"}, | ||
| 200 | {1505, nullptr, "RemoveSdCard"}, | ||
| 201 | {1506, nullptr, "GetSdCardStartupStatus"}, | ||
| 202 | {1600, nullptr, "GetSystemSeedForPseudoDeviceId"}, | ||
| 203 | {1601, nullptr, "ResetSystemSeedForPseudoDeviceId"}, | ||
| 204 | {1700, nullptr, "ListApplicationDownloadingContentMeta"}, | ||
| 205 | {1701, D<&IApplicationManagerInterface::GetApplicationView>, "GetApplicationView"}, | ||
| 206 | {1702, nullptr, "GetApplicationDownloadTaskStatus"}, | ||
| 207 | {1703, nullptr, "GetApplicationViewDownloadErrorContext"}, | ||
| 208 | {1704, D<&IApplicationManagerInterface::GetApplicationViewWithPromotionInfo>, "GetApplicationViewWithPromotionInfo"}, | ||
| 209 | {1705, nullptr, "IsPatchAutoDeletableApplication"}, | ||
| 210 | {1800, nullptr, "IsNotificationSetupCompleted"}, | ||
| 211 | {1801, nullptr, "GetLastNotificationInfoCount"}, | ||
| 212 | {1802, nullptr, "ListLastNotificationInfo"}, | ||
| 213 | {1803, nullptr, "ListNotificationTask"}, | ||
| 214 | {1900, nullptr, "IsActiveAccount"}, | ||
| 215 | {1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"}, | ||
| 216 | {1902, nullptr, "GetApplicationTicketInfo"}, | ||
| 217 | {1903, nullptr, "RequestDownloadApplicationPrepurchasedRightsForAccount"}, | ||
| 218 | {2000, nullptr, "GetSystemDeliveryInfo"}, | ||
| 219 | {2001, nullptr, "SelectLatestSystemDeliveryInfo"}, | ||
| 220 | {2002, nullptr, "VerifyDeliveryProtocolVersion"}, | ||
| 221 | {2003, nullptr, "GetApplicationDeliveryInfo"}, | ||
| 222 | {2004, nullptr, "HasAllContentsToDeliver"}, | ||
| 223 | {2005, nullptr, "CompareApplicationDeliveryInfo"}, | ||
| 224 | {2006, nullptr, "CanDeliverApplication"}, | ||
| 225 | {2007, nullptr, "ListContentMetaKeyToDeliverApplication"}, | ||
| 226 | {2008, nullptr, "NeedsSystemUpdateToDeliverApplication"}, | ||
| 227 | {2009, nullptr, "EstimateRequiredSize"}, | ||
| 228 | {2010, nullptr, "RequestReceiveApplication"}, | ||
| 229 | {2011, nullptr, "CommitReceiveApplication"}, | ||
| 230 | {2012, nullptr, "GetReceiveApplicationProgress"}, | ||
| 231 | {2013, nullptr, "RequestSendApplication"}, | ||
| 232 | {2014, nullptr, "GetSendApplicationProgress"}, | ||
| 233 | {2015, nullptr, "CompareSystemDeliveryInfo"}, | ||
| 234 | {2016, nullptr, "ListNotCommittedContentMeta"}, | ||
| 235 | {2017, nullptr, "CreateDownloadTask"}, | ||
| 236 | {2018, nullptr, "GetApplicationDeliveryInfoHash"}, | ||
| 237 | {2050, D<&IApplicationManagerInterface::GetApplicationRightsOnClient>, "GetApplicationRightsOnClient"}, | ||
| 238 | {2051, nullptr, "InvalidateRightsIdCache"}, | ||
| 239 | {2100, D<&IApplicationManagerInterface::GetApplicationTerminateResult>, "GetApplicationTerminateResult"}, | ||
| 240 | {2101, nullptr, "GetRawApplicationTerminateResult"}, | ||
| 241 | {2150, nullptr, "CreateRightsEnvironment"}, | ||
| 242 | {2151, nullptr, "DestroyRightsEnvironment"}, | ||
| 243 | {2152, nullptr, "ActivateRightsEnvironment"}, | ||
| 244 | {2153, nullptr, "DeactivateRightsEnvironment"}, | ||
| 245 | {2154, nullptr, "ForceActivateRightsContextForExit"}, | ||
| 246 | {2155, nullptr, "UpdateRightsEnvironmentStatus"}, | ||
| 247 | {2156, nullptr, "CreateRightsEnvironmentForMicroApplication"}, | ||
| 248 | {2160, nullptr, "AddTargetApplicationToRightsEnvironment"}, | ||
| 249 | {2161, nullptr, "SetUsersToRightsEnvironment"}, | ||
| 250 | {2170, nullptr, "GetRightsEnvironmentStatus"}, | ||
| 251 | {2171, nullptr, "GetRightsEnvironmentStatusChangedEvent"}, | ||
| 252 | {2180, nullptr, "RequestExtendRightsInRightsEnvironment"}, | ||
| 253 | {2181, nullptr, "GetResultOfExtendRightsInRightsEnvironment"}, | ||
| 254 | {2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"}, | ||
| 255 | {2190, nullptr, "GetRightsEnvironmentHandleForApplication"}, | ||
| 256 | {2199, nullptr, "GetRightsEnvironmentCountForDebug"}, | ||
| 257 | {2200, nullptr, "GetGameCardApplicationCopyIdentifier"}, | ||
| 258 | {2201, nullptr, "GetInstalledApplicationCopyIdentifier"}, | ||
| 259 | {2250, nullptr, "RequestReportActiveELicence"}, | ||
| 260 | {2300, nullptr, "ListEventLog"}, | ||
| 261 | {2350, nullptr, "PerformAutoUpdateByApplicationId"}, | ||
| 262 | {2351, nullptr, "RequestNoDownloadRightsErrorResolution"}, | ||
| 263 | {2352, nullptr, "RequestResolveNoDownloadRightsError"}, | ||
| 264 | {2353, nullptr, "GetApplicationDownloadTaskInfo"}, | ||
| 265 | {2354, nullptr, "PrioritizeApplicationBackgroundTask"}, | ||
| 266 | {2355, nullptr, "PreferStorageEfficientUpdate"}, | ||
| 267 | {2356, nullptr, "RequestStorageEfficientUpdatePreferable"}, | ||
| 268 | {2357, nullptr, "EnableMultiCoreDownload"}, | ||
| 269 | {2358, nullptr, "DisableMultiCoreDownload"}, | ||
| 270 | {2359, nullptr, "IsMultiCoreDownloadEnabled"}, | ||
| 271 | {2400, nullptr, "GetPromotionInfo"}, | ||
| 272 | {2401, nullptr, "CountPromotionInfo"}, | ||
| 273 | {2402, nullptr, "ListPromotionInfo"}, | ||
| 274 | {2403, nullptr, "ImportPromotionJsonForDebug"}, | ||
| 275 | {2404, nullptr, "ClearPromotionInfoForDebug"}, | ||
| 276 | {2500, nullptr, "ConfirmAvailableTime"}, | ||
| 277 | {2510, nullptr, "CreateApplicationResource"}, | ||
| 278 | {2511, nullptr, "GetApplicationResource"}, | ||
| 279 | {2513, nullptr, "LaunchMicroApplication"}, | ||
| 280 | {2514, nullptr, "ClearTaskOfAsyncTaskManager"}, | ||
| 281 | {2515, nullptr, "CleanupAllPlaceHolderAndFragmentsIfNoTask"}, | ||
| 282 | {2516, nullptr, "EnsureApplicationCertificate"}, | ||
| 283 | {2517, nullptr, "CreateApplicationInstance"}, | ||
| 284 | {2518, nullptr, "UpdateQualificationForDebug"}, | ||
| 285 | {2519, nullptr, "IsQualificationTransitionSupported"}, | ||
| 286 | {2520, nullptr, "IsQualificationTransitionSupportedByProcessId"}, | ||
| 287 | {2521, nullptr, "GetRightsUserChangedEvent"}, | ||
| 288 | {2522, nullptr, "IsRomRedirectionAvailable"}, | ||
| 289 | {2800, nullptr, "GetApplicationIdOfPreomia"}, | ||
| 290 | {3000, nullptr, "RegisterDeviceLockKey"}, | ||
| 291 | {3001, nullptr, "UnregisterDeviceLockKey"}, | ||
| 292 | {3002, nullptr, "VerifyDeviceLockKey"}, | ||
| 293 | {3003, nullptr, "HideApplicationIcon"}, | ||
| 294 | {3004, nullptr, "ShowApplicationIcon"}, | ||
| 295 | {3005, nullptr, "HideApplicationTitle"}, | ||
| 296 | {3006, nullptr, "ShowApplicationTitle"}, | ||
| 297 | {3007, nullptr, "EnableGameCard"}, | ||
| 298 | {3008, nullptr, "DisableGameCard"}, | ||
| 299 | {3009, nullptr, "EnableLocalContentShare"}, | ||
| 300 | {3010, nullptr, "DisableLocalContentShare"}, | ||
| 301 | {3011, nullptr, "IsApplicationIconHidden"}, | ||
| 302 | {3012, nullptr, "IsApplicationTitleHidden"}, | ||
| 303 | {3013, nullptr, "IsGameCardEnabled"}, | ||
| 304 | {3014, nullptr, "IsLocalContentShareEnabled"}, | ||
| 305 | {3050, nullptr, "ListAssignELicenseTaskResult"}, | ||
| 306 | {9999, nullptr, "GetApplicationCertificate"}, | ||
| 307 | }; | ||
| 308 | // clang-format on | ||
| 309 | |||
| 310 | RegisterHandlers(functions); | ||
| 311 | } | ||
| 312 | |||
| 313 | IApplicationManagerInterface::~IApplicationManagerInterface() = default; | ||
| 314 | |||
| 315 | Result IApplicationManagerInterface::GetApplicationControlData( | ||
| 316 | OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u32> out_actual_size, | ||
| 317 | ApplicationControlSource application_control_source, u64 application_id) { | ||
| 318 | LOG_DEBUG(Service_NS, "called"); | ||
| 319 | R_RETURN(IReadOnlyApplicationControlDataInterface(system).GetApplicationControlData( | ||
| 320 | out_buffer, out_actual_size, application_control_source, application_id)); | ||
| 321 | } | ||
| 322 | |||
| 323 | Result IApplicationManagerInterface::GetApplicationDesiredLanguage( | ||
| 324 | Out<ApplicationLanguage> out_desired_language, u32 supported_languages) { | ||
| 325 | LOG_DEBUG(Service_NS, "called"); | ||
| 326 | R_RETURN(IReadOnlyApplicationControlDataInterface(system).GetApplicationDesiredLanguage( | ||
| 327 | out_desired_language, supported_languages)); | ||
| 328 | } | ||
| 329 | |||
| 330 | Result IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode( | ||
| 331 | Out<u64> out_language_code, ApplicationLanguage application_language) { | ||
| 332 | LOG_DEBUG(Service_NS, "called"); | ||
| 333 | R_RETURN( | ||
| 334 | IReadOnlyApplicationControlDataInterface(system).ConvertApplicationLanguageToLanguageCode( | ||
| 335 | out_language_code, application_language)); | ||
| 336 | } | ||
| 337 | |||
| 338 | Result IApplicationManagerInterface::ListApplicationRecord( | ||
| 339 | OutArray<ApplicationRecord, BufferAttr_HipcMapAlias> out_records, Out<s32> out_count, | ||
| 340 | s32 offset) { | ||
| 341 | const auto limit = out_records.size(); | ||
| 342 | |||
| 343 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 344 | const auto& cache = system.GetContentProviderUnion(); | ||
| 345 | const auto installed_games = cache.ListEntriesFilterOrigin( | ||
| 346 | std::nullopt, FileSys::TitleType::Application, FileSys::ContentRecordType::Program); | ||
| 347 | |||
| 348 | size_t i = 0; | ||
| 349 | u8 ii = 24; | ||
| 350 | |||
| 351 | for (const auto& [slot, game] : installed_games) { | ||
| 352 | if (i >= limit) { | ||
| 353 | break; | ||
| 354 | } | ||
| 355 | if (game.title_id == 0 || game.title_id < 0x0100000000001FFFull) { | ||
| 356 | continue; | ||
| 357 | } | ||
| 358 | if (offset > 0) { | ||
| 359 | offset--; | ||
| 360 | continue; | ||
| 361 | } | ||
| 362 | |||
| 363 | ApplicationRecord record{}; | ||
| 364 | record.application_id = game.title_id; | ||
| 365 | record.type = ApplicationRecordType::Installed; | ||
| 366 | record.unknown = 0; // 2 = needs update | ||
| 367 | record.unknown2 = ii++; | ||
| 368 | |||
| 369 | out_records[i++] = record; | ||
| 370 | } | ||
| 371 | |||
| 372 | *out_count = static_cast<s32>(i); | ||
| 373 | R_SUCCEED(); | ||
| 374 | } | ||
| 375 | |||
| 376 | Result IApplicationManagerInterface::GetApplicationRecordUpdateSystemEvent( | ||
| 377 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 378 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 379 | |||
| 380 | record_update_system_event.Signal(); | ||
| 381 | *out_event = record_update_system_event.GetHandle(); | ||
| 382 | |||
| 383 | R_SUCCEED(); | ||
| 384 | } | ||
| 385 | |||
| 386 | Result IApplicationManagerInterface::GetGameCardMountFailureEvent( | ||
| 387 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 388 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 389 | *out_event = gamecard_mount_failure_event.GetHandle(); | ||
| 390 | R_SUCCEED(); | ||
| 391 | } | ||
| 392 | |||
| 393 | Result IApplicationManagerInterface::IsAnyApplicationEntityInstalled( | ||
| 394 | Out<bool> out_is_any_application_entity_installed) { | ||
| 395 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 396 | *out_is_any_application_entity_installed = true; | ||
| 397 | R_SUCCEED(); | ||
| 398 | } | ||
| 399 | |||
| 400 | Result IApplicationManagerInterface::GetApplicationView( | ||
| 401 | OutArray<ApplicationView, BufferAttr_HipcMapAlias> out_application_views, | ||
| 402 | InArray<u64, BufferAttr_HipcMapAlias> application_ids) { | ||
| 403 | const auto size = std::min(out_application_views.size(), application_ids.size()); | ||
| 404 | LOG_WARNING(Service_NS, "(STUBBED) called, size={}", application_ids.size()); | ||
| 405 | |||
| 406 | for (size_t i = 0; i < size; i++) { | ||
| 407 | ApplicationView view{}; | ||
| 408 | view.application_id = application_ids[i]; | ||
| 409 | view.unk = 0x70000; | ||
| 410 | view.flags = 0x401f17; | ||
| 411 | |||
| 412 | out_application_views[i] = view; | ||
| 413 | } | ||
| 414 | |||
| 415 | R_SUCCEED(); | ||
| 416 | } | ||
| 417 | |||
| 418 | Result IApplicationManagerInterface::GetApplicationViewWithPromotionInfo( | ||
| 419 | OutArray<ApplicationViewWithPromotionInfo, BufferAttr_HipcMapAlias> out_application_views, | ||
| 420 | InArray<u64, BufferAttr_HipcMapAlias> application_ids) { | ||
| 421 | const auto size = std::min(out_application_views.size(), application_ids.size()); | ||
| 422 | LOG_WARNING(Service_NS, "(STUBBED) called, size={}", application_ids.size()); | ||
| 423 | |||
| 424 | for (size_t i = 0; i < size; i++) { | ||
| 425 | ApplicationViewWithPromotionInfo view{}; | ||
| 426 | view.view.application_id = application_ids[i]; | ||
| 427 | view.view.unk = 0x70000; | ||
| 428 | view.view.flags = 0x401f17; | ||
| 429 | view.promotion = {}; | ||
| 430 | |||
| 431 | out_application_views[i] = view; | ||
| 432 | } | ||
| 433 | |||
| 434 | R_SUCCEED(); | ||
| 435 | } | ||
| 436 | |||
| 437 | Result IApplicationManagerInterface::GetApplicationRightsOnClient( | ||
| 438 | OutArray<ApplicationRightsOnClient, BufferAttr_HipcMapAlias> out_rights, Out<u32> out_count, | ||
| 439 | u32 flags, u64 application_id, Uid account_id) { | ||
| 440 | LOG_WARNING(Service_NS, "(STUBBED) called, flags={}, application_id={:016X}, account_id={}", | ||
| 441 | flags, application_id, account_id.uuid.FormattedString()); | ||
| 442 | |||
| 443 | if (!out_rights.empty()) { | ||
| 444 | ApplicationRightsOnClient rights{}; | ||
| 445 | rights.application_id = application_id; | ||
| 446 | rights.uid = account_id.uuid; | ||
| 447 | rights.flags = 0; | ||
| 448 | rights.flags2 = 0; | ||
| 449 | |||
| 450 | out_rights[0] = rights; | ||
| 451 | *out_count = 1; | ||
| 452 | } else { | ||
| 453 | *out_count = 0; | ||
| 454 | } | ||
| 455 | |||
| 456 | R_SUCCEED(); | ||
| 457 | } | ||
| 458 | |||
| 459 | Result IApplicationManagerInterface::CheckSdCardMountStatus() { | ||
| 460 | LOG_DEBUG(Service_NS, "called"); | ||
| 461 | R_RETURN(IContentManagementInterface(system).CheckSdCardMountStatus()); | ||
| 462 | } | ||
| 463 | |||
| 464 | Result IApplicationManagerInterface::GetSdCardMountStatusChangedEvent( | ||
| 465 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 466 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 467 | *out_event = sd_card_mount_status_event.GetHandle(); | ||
| 468 | R_SUCCEED(); | ||
| 469 | } | ||
| 470 | |||
| 471 | Result IApplicationManagerInterface::GetFreeSpaceSize(Out<s64> out_free_space_size, | ||
| 472 | FileSys::StorageId storage_id) { | ||
| 473 | LOG_DEBUG(Service_NS, "called"); | ||
| 474 | R_RETURN(IContentManagementInterface(system).GetFreeSpaceSize(out_free_space_size, storage_id)); | ||
| 475 | } | ||
| 476 | |||
| 477 | Result IApplicationManagerInterface::GetGameCardUpdateDetectionEvent( | ||
| 478 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 479 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 480 | *out_event = gamecard_update_detection_event.GetHandle(); | ||
| 481 | R_SUCCEED(); | ||
| 482 | } | ||
| 483 | |||
| 484 | Result IApplicationManagerInterface::ResumeAll() { | ||
| 485 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 486 | R_SUCCEED(); | ||
| 487 | } | ||
| 488 | |||
| 489 | Result IApplicationManagerInterface::GetStorageSize(Out<s64> out_total_space_size, | ||
| 490 | Out<s64> out_free_space_size, | ||
| 491 | FileSys::StorageId storage_id) { | ||
| 492 | LOG_INFO(Service_NS, "called, storage_id={}", storage_id); | ||
| 493 | *out_total_space_size = system.GetFileSystemController().GetTotalSpaceSize(storage_id); | ||
| 494 | *out_free_space_size = system.GetFileSystemController().GetFreeSpaceSize(storage_id); | ||
| 495 | R_SUCCEED(); | ||
| 496 | } | ||
| 497 | |||
| 498 | Result IApplicationManagerInterface::IsApplicationUpdateRequested(Out<bool> out_update_required, | ||
| 499 | Out<u32> out_update_version, | ||
| 500 | u64 application_id) { | ||
| 501 | LOG_WARNING(Service_NS, "(STUBBED) called. application_id={:016X}", application_id); | ||
| 502 | *out_update_required = false; | ||
| 503 | *out_update_version = 0; | ||
| 504 | R_SUCCEED(); | ||
| 505 | } | ||
| 506 | |||
| 507 | Result IApplicationManagerInterface::CheckApplicationLaunchVersion(u64 application_id) { | ||
| 508 | LOG_WARNING(Service_NS, "(STUBBED) called. application_id={:016X}", application_id); | ||
| 509 | R_SUCCEED(); | ||
| 510 | } | ||
| 511 | |||
| 512 | Result IApplicationManagerInterface::GetApplicationTerminateResult(Out<Result> out_result, | ||
| 513 | u64 application_id) { | ||
| 514 | LOG_WARNING(Service_NS, "(STUBBED) called. application_id={:016X}", application_id); | ||
| 515 | *out_result = ResultSuccess; | ||
| 516 | R_SUCCEED(); | ||
| 517 | } | ||
| 518 | |||
| 519 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/application_manager_interface.h b/src/core/hle/service/ns/application_manager_interface.h new file mode 100644 index 000000000..f33d269b3 --- /dev/null +++ b/src/core/hle/service/ns/application_manager_interface.h | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/ns/language.h" | ||
| 8 | #include "core/hle/service/ns/ns_types.h" | ||
| 9 | #include "core/hle/service/os/event.h" | ||
| 10 | #include "core/hle/service/service.h" | ||
| 11 | |||
| 12 | namespace Service::NS { | ||
| 13 | |||
| 14 | class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> { | ||
| 15 | public: | ||
| 16 | explicit IApplicationManagerInterface(Core::System& system_); | ||
| 17 | ~IApplicationManagerInterface() override; | ||
| 18 | |||
| 19 | Result GetApplicationControlData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer, | ||
| 20 | Out<u32> out_actual_size, | ||
| 21 | ApplicationControlSource application_control_source, | ||
| 22 | u64 application_id); | ||
| 23 | Result GetApplicationDesiredLanguage(Out<ApplicationLanguage> out_desired_language, | ||
| 24 | u32 supported_languages); | ||
| 25 | Result ConvertApplicationLanguageToLanguageCode(Out<u64> out_language_code, | ||
| 26 | ApplicationLanguage application_language); | ||
| 27 | Result ListApplicationRecord(OutArray<ApplicationRecord, BufferAttr_HipcMapAlias> out_records, | ||
| 28 | Out<s32> out_count, s32 offset); | ||
| 29 | Result GetApplicationRecordUpdateSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 30 | Result GetGameCardMountFailureEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 31 | Result IsAnyApplicationEntityInstalled(Out<bool> out_is_any_application_entity_installed); | ||
| 32 | Result GetApplicationView( | ||
| 33 | OutArray<ApplicationView, BufferAttr_HipcMapAlias> out_application_views, | ||
| 34 | InArray<u64, BufferAttr_HipcMapAlias> application_ids); | ||
| 35 | Result GetApplicationViewWithPromotionInfo( | ||
| 36 | OutArray<ApplicationViewWithPromotionInfo, BufferAttr_HipcMapAlias> out_application_views, | ||
| 37 | InArray<u64, BufferAttr_HipcMapAlias> application_ids); | ||
| 38 | Result GetApplicationRightsOnClient( | ||
| 39 | OutArray<ApplicationRightsOnClient, BufferAttr_HipcMapAlias> out_rights, Out<u32> out_count, | ||
| 40 | u32 flags, u64 application_id, Uid account_id); | ||
| 41 | Result CheckSdCardMountStatus(); | ||
| 42 | Result GetSdCardMountStatusChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 43 | Result GetFreeSpaceSize(Out<s64> out_free_space_size, FileSys::StorageId storage_id); | ||
| 44 | Result GetGameCardUpdateDetectionEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 45 | Result ResumeAll(); | ||
| 46 | Result GetStorageSize(Out<s64> out_total_space_size, Out<s64> out_free_space_size, | ||
| 47 | FileSys::StorageId storage_id); | ||
| 48 | Result IsApplicationUpdateRequested(Out<bool> out_update_required, Out<u32> out_update_version, | ||
| 49 | u64 application_id); | ||
| 50 | Result CheckApplicationLaunchVersion(u64 application_id); | ||
| 51 | Result GetApplicationTerminateResult(Out<Result> out_result, u64 application_id); | ||
| 52 | |||
| 53 | private: | ||
| 54 | KernelHelpers::ServiceContext service_context; | ||
| 55 | Event record_update_system_event; | ||
| 56 | Event sd_card_mount_status_event; | ||
| 57 | Event gamecard_update_detection_event; | ||
| 58 | Event gamecard_mount_status_event; | ||
| 59 | Event gamecard_mount_failure_event; | ||
| 60 | }; | ||
| 61 | |||
| 62 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/application_version_interface.cpp b/src/core/hle/service/ns/application_version_interface.cpp new file mode 100644 index 000000000..b89e127db --- /dev/null +++ b/src/core/hle/service/ns/application_version_interface.cpp | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/ns/application_version_interface.h" | ||
| 5 | |||
| 6 | namespace Service::NS { | ||
| 7 | |||
| 8 | IApplicationVersionInterface::IApplicationVersionInterface(Core::System& system_) | ||
| 9 | : ServiceFramework{system_, "IApplicationVersionInterface"} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, nullptr, "GetLaunchRequiredVersion"}, | ||
| 13 | {1, nullptr, "UpgradeLaunchRequiredVersion"}, | ||
| 14 | {35, nullptr, "UpdateVersionList"}, | ||
| 15 | {36, nullptr, "PushLaunchVersion"}, | ||
| 16 | {37, nullptr, "ListRequiredVersion"}, | ||
| 17 | {800, nullptr, "RequestVersionList"}, | ||
| 18 | {801, nullptr, "ListVersionList"}, | ||
| 19 | {802, nullptr, "RequestVersionListData"}, | ||
| 20 | {900, nullptr, "ImportAutoUpdatePolicyJsonForDebug"}, | ||
| 21 | {901, nullptr, "ListDefaultAutoUpdatePolicy"}, | ||
| 22 | {902, nullptr, "ListAutoUpdatePolicyForSpecificApplication"}, | ||
| 23 | {1000, nullptr, "PerformAutoUpdate"}, | ||
| 24 | {1001, nullptr, "ListAutoUpdateSchedule"}, | ||
| 25 | }; | ||
| 26 | // clang-format on | ||
| 27 | |||
| 28 | RegisterHandlers(functions); | ||
| 29 | } | ||
| 30 | |||
| 31 | IApplicationVersionInterface::~IApplicationVersionInterface() = default; | ||
| 32 | |||
| 33 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/application_version_interface.h b/src/core/hle/service/ns/application_version_interface.h new file mode 100644 index 000000000..b288cff1b --- /dev/null +++ b/src/core/hle/service/ns/application_version_interface.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::NS { | ||
| 9 | |||
| 10 | class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> { | ||
| 11 | public: | ||
| 12 | explicit IApplicationVersionInterface(Core::System& system_); | ||
| 13 | ~IApplicationVersionInterface() override; | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/content_management_interface.cpp b/src/core/hle/service/ns/content_management_interface.cpp new file mode 100644 index 000000000..69bb3f6e4 --- /dev/null +++ b/src/core/hle/service/ns/content_management_interface.cpp | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/common_funcs.h" | ||
| 5 | #include "core/core.h" | ||
| 6 | #include "core/hle/service/cmif_serialization.h" | ||
| 7 | #include "core/hle/service/filesystem/filesystem.h" | ||
| 8 | #include "core/hle/service/ns/content_management_interface.h" | ||
| 9 | #include "core/hle/service/ns/ns_types.h" | ||
| 10 | |||
| 11 | namespace Service::NS { | ||
| 12 | |||
| 13 | IContentManagementInterface::IContentManagementInterface(Core::System& system_) | ||
| 14 | : ServiceFramework{system_, "IContentManagementInterface"} { | ||
| 15 | // clang-format off | ||
| 16 | static const FunctionInfo functions[] = { | ||
| 17 | {11, D<&IContentManagementInterface::CalculateApplicationOccupiedSize>, "CalculateApplicationOccupiedSize"}, | ||
| 18 | {43, D<&IContentManagementInterface::CheckSdCardMountStatus>, "CheckSdCardMountStatus"}, | ||
| 19 | {47, D<&IContentManagementInterface::GetTotalSpaceSize>, "GetTotalSpaceSize"}, | ||
| 20 | {48, D<&IContentManagementInterface::GetFreeSpaceSize>, "GetFreeSpaceSize"}, | ||
| 21 | {600, nullptr, "CountApplicationContentMeta"}, | ||
| 22 | {601, nullptr, "ListApplicationContentMetaStatus"}, | ||
| 23 | {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"}, | ||
| 24 | {607, nullptr, "IsAnyApplicationRunning"}, | ||
| 25 | }; | ||
| 26 | // clang-format on | ||
| 27 | |||
| 28 | RegisterHandlers(functions); | ||
| 29 | } | ||
| 30 | |||
| 31 | IContentManagementInterface::~IContentManagementInterface() = default; | ||
| 32 | |||
| 33 | Result IContentManagementInterface::CalculateApplicationOccupiedSize( | ||
| 34 | Out<ApplicationOccupiedSize> out_size, u64 application_id) { | ||
| 35 | LOG_WARNING(Service_NS, "(STUBBED) called, application_id={:016X}", application_id); | ||
| 36 | |||
| 37 | using namespace Common::Literals; | ||
| 38 | |||
| 39 | constexpr ApplicationOccupiedSizeEntity stub_entity{ | ||
| 40 | .storage_id = FileSys::StorageId::SdCard, | ||
| 41 | .app_size = 8_GiB, | ||
| 42 | .patch_size = 2_GiB, | ||
| 43 | .aoc_size = 12_MiB, | ||
| 44 | }; | ||
| 45 | |||
| 46 | for (auto& entity : out_size->entities) { | ||
| 47 | entity = stub_entity; | ||
| 48 | } | ||
| 49 | |||
| 50 | R_SUCCEED(); | ||
| 51 | } | ||
| 52 | |||
| 53 | Result IContentManagementInterface::CheckSdCardMountStatus() { | ||
| 54 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 55 | R_SUCCEED(); | ||
| 56 | } | ||
| 57 | |||
| 58 | Result IContentManagementInterface::GetTotalSpaceSize(Out<s64> out_total_space_size, | ||
| 59 | FileSys::StorageId storage_id) { | ||
| 60 | LOG_INFO(Service_NS, "(STUBBED) called, storage_id={}", storage_id); | ||
| 61 | *out_total_space_size = system.GetFileSystemController().GetTotalSpaceSize(storage_id); | ||
| 62 | R_SUCCEED(); | ||
| 63 | } | ||
| 64 | |||
| 65 | Result IContentManagementInterface::GetFreeSpaceSize(Out<s64> out_free_space_size, | ||
| 66 | FileSys::StorageId storage_id) { | ||
| 67 | LOG_INFO(Service_NS, "(STUBBED) called, storage_id={}", storage_id); | ||
| 68 | *out_free_space_size = system.GetFileSystemController().GetFreeSpaceSize(storage_id); | ||
| 69 | R_SUCCEED(); | ||
| 70 | } | ||
| 71 | |||
| 72 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/content_management_interface.h b/src/core/hle/service/ns/content_management_interface.h new file mode 100644 index 000000000..2894628e5 --- /dev/null +++ b/src/core/hle/service/ns/content_management_interface.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/ns/ns_types.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | |||
| 10 | namespace Service::NS { | ||
| 11 | |||
| 12 | class IContentManagementInterface final : public ServiceFramework<IContentManagementInterface> { | ||
| 13 | public: | ||
| 14 | explicit IContentManagementInterface(Core::System& system_); | ||
| 15 | ~IContentManagementInterface() override; | ||
| 16 | |||
| 17 | public: | ||
| 18 | Result CalculateApplicationOccupiedSize(Out<ApplicationOccupiedSize> out_size, | ||
| 19 | u64 application_id); | ||
| 20 | Result CheckSdCardMountStatus(); | ||
| 21 | Result GetTotalSpaceSize(Out<s64> out_total_space_size, FileSys::StorageId storage_id); | ||
| 22 | Result GetFreeSpaceSize(Out<s64> out_free_space_size, FileSys::StorageId storage_id); | ||
| 23 | }; | ||
| 24 | |||
| 25 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/develop_interface.cpp b/src/core/hle/service/ns/develop_interface.cpp new file mode 100644 index 000000000..880bdbebb --- /dev/null +++ b/src/core/hle/service/ns/develop_interface.cpp | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/ns/develop_interface.h" | ||
| 5 | |||
| 6 | namespace Service::NS { | ||
| 7 | |||
| 8 | IDevelopInterface::IDevelopInterface(Core::System& system_) : ServiceFramework{system_, "ns:dev"} { | ||
| 9 | // clang-format off | ||
| 10 | static const FunctionInfo functions[] = { | ||
| 11 | {0, nullptr, "LaunchProgram"}, | ||
| 12 | {1, nullptr, "TerminateProcess"}, | ||
| 13 | {2, nullptr, "TerminateProgram"}, | ||
| 14 | {4, nullptr, "GetShellEvent"}, | ||
| 15 | {5, nullptr, "GetShellEventInfo"}, | ||
| 16 | {6, nullptr, "TerminateApplication"}, | ||
| 17 | {7, nullptr, "PrepareLaunchProgramFromHost"}, | ||
| 18 | {8, nullptr, "LaunchApplicationFromHost"}, | ||
| 19 | {9, nullptr, "LaunchApplicationWithStorageIdForDevelop"}, | ||
| 20 | {10, nullptr, "IsSystemMemoryResourceLimitBoosted"}, | ||
| 21 | {11, nullptr, "GetRunningApplicationProcessIdForDevelop"}, | ||
| 22 | {12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop"}, | ||
| 23 | {13, nullptr, "CreateApplicationResourceForDevelop"}, | ||
| 24 | {14, nullptr, "IsPreomiaForDevelop"}, | ||
| 25 | {15, nullptr, "GetApplicationProgramIdFromHost"}, | ||
| 26 | {16, nullptr, "RefreshCachedDebugValues"}, | ||
| 27 | {17, nullptr, "PrepareLaunchApplicationFromHost"}, | ||
| 28 | {18, nullptr, "GetLaunchEvent"}, | ||
| 29 | {19, nullptr, "GetLaunchResult"}, | ||
| 30 | }; | ||
| 31 | // clang-format on | ||
| 32 | |||
| 33 | RegisterHandlers(functions); | ||
| 34 | } | ||
| 35 | |||
| 36 | IDevelopInterface::~IDevelopInterface() = default; | ||
| 37 | |||
| 38 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/develop_interface.h b/src/core/hle/service/ns/develop_interface.h new file mode 100644 index 000000000..a9f81ccd6 --- /dev/null +++ b/src/core/hle/service/ns/develop_interface.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::NS { | ||
| 9 | |||
| 10 | class IDevelopInterface final : public ServiceFramework<IDevelopInterface> { | ||
| 11 | public: | ||
| 12 | explicit IDevelopInterface(Core::System& system_); | ||
| 13 | ~IDevelopInterface() override; | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/document_interface.cpp b/src/core/hle/service/ns/document_interface.cpp new file mode 100644 index 000000000..51a1e46c0 --- /dev/null +++ b/src/core/hle/service/ns/document_interface.cpp | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/core.h" | ||
| 5 | #include "core/hle/service/cmif_serialization.h" | ||
| 6 | #include "core/hle/service/ns/document_interface.h" | ||
| 7 | |||
| 8 | namespace Service::NS { | ||
| 9 | |||
| 10 | IDocumentInterface::IDocumentInterface(Core::System& system_) | ||
| 11 | : ServiceFramework{system_, "IDocumentInterface"} { | ||
| 12 | // clang-format off | ||
| 13 | static const FunctionInfo functions[] = { | ||
| 14 | {21, nullptr, "GetApplicationContentPath"}, | ||
| 15 | {23, D<&IDocumentInterface::ResolveApplicationContentPath>, "ResolveApplicationContentPath"}, | ||
| 16 | {92, D<&IDocumentInterface::GetRunningApplicationProgramId>, "GetRunningApplicationProgramId"}, | ||
| 17 | }; | ||
| 18 | // clang-format on | ||
| 19 | |||
| 20 | RegisterHandlers(functions); | ||
| 21 | } | ||
| 22 | |||
| 23 | IDocumentInterface::~IDocumentInterface() = default; | ||
| 24 | |||
| 25 | Result IDocumentInterface::ResolveApplicationContentPath(ContentPath content_path) { | ||
| 26 | LOG_WARNING(Service_NS, "(STUBBED) called, file_system_proxy_type={}, program_id={:016X}", | ||
| 27 | content_path.file_system_proxy_type, content_path.program_id); | ||
| 28 | R_SUCCEED(); | ||
| 29 | } | ||
| 30 | |||
| 31 | Result IDocumentInterface::GetRunningApplicationProgramId(Out<u64> out_program_id, | ||
| 32 | u64 caller_program_id) { | ||
| 33 | LOG_WARNING(Service_NS, "(STUBBED) called, caller_program_id={:016X}", caller_program_id); | ||
| 34 | *out_program_id = system.GetApplicationProcessProgramID(); | ||
| 35 | R_SUCCEED(); | ||
| 36 | } | ||
| 37 | |||
| 38 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/document_interface.h b/src/core/hle/service/ns/document_interface.h new file mode 100644 index 000000000..cd461652c --- /dev/null +++ b/src/core/hle/service/ns/document_interface.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/ns/ns_types.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | |||
| 10 | namespace Service::NS { | ||
| 11 | |||
| 12 | class IDocumentInterface final : public ServiceFramework<IDocumentInterface> { | ||
| 13 | public: | ||
| 14 | explicit IDocumentInterface(Core::System& system_); | ||
| 15 | ~IDocumentInterface() override; | ||
| 16 | |||
| 17 | private: | ||
| 18 | Result ResolveApplicationContentPath(ContentPath content_path); | ||
| 19 | Result GetRunningApplicationProgramId(Out<u64> out_program_id, u64 caller_program_id); | ||
| 20 | }; | ||
| 21 | |||
| 22 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/download_task_interface.cpp b/src/core/hle/service/ns/download_task_interface.cpp new file mode 100644 index 000000000..62dc7f187 --- /dev/null +++ b/src/core/hle/service/ns/download_task_interface.cpp | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/cmif_serialization.h" | ||
| 5 | #include "core/hle/service/ns/download_task_interface.h" | ||
| 6 | |||
| 7 | namespace Service::NS { | ||
| 8 | |||
| 9 | IDownloadTaskInterface::IDownloadTaskInterface(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "IDownloadTaskInterface"} { | ||
| 11 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | ||
| 13 | {701, nullptr, "ClearTaskStatusList"}, | ||
| 14 | {702, nullptr, "RequestDownloadTaskList"}, | ||
| 15 | {703, nullptr, "RequestEnsureDownloadTask"}, | ||
| 16 | {704, nullptr, "ListDownloadTaskStatus"}, | ||
| 17 | {705, nullptr, "RequestDownloadTaskListData"}, | ||
| 18 | {706, nullptr, "TryCommitCurrentApplicationDownloadTask"}, | ||
| 19 | {707, D<&IDownloadTaskInterface::EnableAutoCommit>, "EnableAutoCommit"}, | ||
| 20 | {708, D<&IDownloadTaskInterface::DisableAutoCommit>, "DisableAutoCommit"}, | ||
| 21 | {709, nullptr, "TriggerDynamicCommitEvent"}, | ||
| 22 | }; | ||
| 23 | // clang-format on | ||
| 24 | |||
| 25 | RegisterHandlers(functions); | ||
| 26 | } | ||
| 27 | |||
| 28 | IDownloadTaskInterface::~IDownloadTaskInterface() = default; | ||
| 29 | |||
| 30 | Result IDownloadTaskInterface::EnableAutoCommit() { | ||
| 31 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 32 | R_SUCCEED(); | ||
| 33 | } | ||
| 34 | Result IDownloadTaskInterface::DisableAutoCommit() { | ||
| 35 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 36 | R_SUCCEED(); | ||
| 37 | } | ||
| 38 | |||
| 39 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/download_task_interface.h b/src/core/hle/service/ns/download_task_interface.h new file mode 100644 index 000000000..b1cb69cb8 --- /dev/null +++ b/src/core/hle/service/ns/download_task_interface.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::NS { | ||
| 9 | |||
| 10 | class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> { | ||
| 11 | public: | ||
| 12 | explicit IDownloadTaskInterface(Core::System& system_); | ||
| 13 | ~IDownloadTaskInterface() override; | ||
| 14 | |||
| 15 | private: | ||
| 16 | Result EnableAutoCommit(); | ||
| 17 | Result DisableAutoCommit(); | ||
| 18 | }; | ||
| 19 | |||
| 20 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/dynamic_rights_interface.cpp b/src/core/hle/service/ns/dynamic_rights_interface.cpp new file mode 100644 index 000000000..ce81e203f --- /dev/null +++ b/src/core/hle/service/ns/dynamic_rights_interface.cpp | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/cmif_serialization.h" | ||
| 5 | #include "core/hle/service/ns/dynamic_rights_interface.h" | ||
| 6 | |||
| 7 | namespace Service::NS { | ||
| 8 | |||
| 9 | IDynamicRightsInterface::IDynamicRightsInterface(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "DynamicRightsInterface"} { | ||
| 11 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | ||
| 13 | {0, nullptr, "RequestApplicationRightsOnServer"}, | ||
| 14 | {1, nullptr, "RequestAssignRights"}, | ||
| 15 | {4, nullptr, "DeprecatedRequestAssignRightsToResume"}, | ||
| 16 | {5, D<&IDynamicRightsInterface::VerifyActivatedRightsOwners>, "VerifyActivatedRightsOwners"}, | ||
| 17 | {6, nullptr, "DeprecatedGetApplicationRightsStatus"}, | ||
| 18 | {7, nullptr, "RequestPrefetchForDynamicRights"}, | ||
| 19 | {8, nullptr, "GetDynamicRightsState"}, | ||
| 20 | {9, nullptr, "RequestApplicationRightsOnServerToResume"}, | ||
| 21 | {10, nullptr, "RequestAssignRightsToResume"}, | ||
| 22 | {11, nullptr, "GetActivatedRightsUsers"}, | ||
| 23 | {12, nullptr, "GetApplicationRightsStatus"}, | ||
| 24 | {13, D<&IDynamicRightsInterface::GetRunningApplicationStatus>, "GetRunningApplicationStatus"}, | ||
| 25 | {14, nullptr, "SelectApplicationLicense"}, | ||
| 26 | {15, nullptr, "RequestContentsAuthorizationToken"}, | ||
| 27 | {16, nullptr, "QualifyUser"}, | ||
| 28 | {17, nullptr, "QualifyUserWithProcessId"}, | ||
| 29 | {18, D<&IDynamicRightsInterface::NotifyApplicationRightsCheckStart>, "NotifyApplicationRightsCheckStart"}, | ||
| 30 | {19, nullptr, "UpdateUserList"}, | ||
| 31 | {20, nullptr, "IsRightsLostUser"}, | ||
| 32 | {21, nullptr, "SetRequiredAddOnContentsOnContentsAvailabilityTransition"}, | ||
| 33 | {22, nullptr, "GetLimitedApplicationLicense"}, | ||
| 34 | {23, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"}, | ||
| 35 | {24, nullptr, "NotifyLimitedApplicationLicenseUpgradableEventForDebug"}, | ||
| 36 | {25, nullptr, "RequestProceedDynamicRightsState"}, | ||
| 37 | }; | ||
| 38 | // clang-format on | ||
| 39 | |||
| 40 | RegisterHandlers(functions); | ||
| 41 | } | ||
| 42 | |||
| 43 | IDynamicRightsInterface::~IDynamicRightsInterface() = default; | ||
| 44 | |||
| 45 | Result IDynamicRightsInterface::NotifyApplicationRightsCheckStart() { | ||
| 46 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 47 | R_SUCCEED(); | ||
| 48 | } | ||
| 49 | |||
| 50 | Result IDynamicRightsInterface::GetRunningApplicationStatus(Out<u32> out_status, | ||
| 51 | u64 rights_handle) { | ||
| 52 | LOG_WARNING(Service_NS, "(STUBBED) called, rights_handle={:#x}", rights_handle); | ||
| 53 | *out_status = 0; | ||
| 54 | R_SUCCEED(); | ||
| 55 | } | ||
| 56 | |||
| 57 | Result IDynamicRightsInterface::VerifyActivatedRightsOwners(u64 rights_handle) { | ||
| 58 | LOG_WARNING(Service_NS, "(STUBBED) called, rights_handle={:#x}", rights_handle); | ||
| 59 | R_SUCCEED(); | ||
| 60 | } | ||
| 61 | |||
| 62 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/dynamic_rights_interface.h b/src/core/hle/service/ns/dynamic_rights_interface.h new file mode 100644 index 000000000..877e009b0 --- /dev/null +++ b/src/core/hle/service/ns/dynamic_rights_interface.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::NS { | ||
| 10 | |||
| 11 | class IDynamicRightsInterface final : public ServiceFramework<IDynamicRightsInterface> { | ||
| 12 | public: | ||
| 13 | explicit IDynamicRightsInterface(Core::System& system_); | ||
| 14 | ~IDynamicRightsInterface() override; | ||
| 15 | |||
| 16 | private: | ||
| 17 | Result NotifyApplicationRightsCheckStart(); | ||
| 18 | Result GetRunningApplicationStatus(Out<u32> out_status, u64 rights_handle); | ||
| 19 | Result VerifyActivatedRightsOwners(u64 rights_handle); | ||
| 20 | }; | ||
| 21 | |||
| 22 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/ecommerce_interface.cpp b/src/core/hle/service/ns/ecommerce_interface.cpp new file mode 100644 index 000000000..76fc425f0 --- /dev/null +++ b/src/core/hle/service/ns/ecommerce_interface.cpp | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/ns/ecommerce_interface.h" | ||
| 5 | |||
| 6 | namespace Service::NS { | ||
| 7 | |||
| 8 | IECommerceInterface::IECommerceInterface(Core::System& system_) | ||
| 9 | : ServiceFramework{system_, "IECommerceInterface"} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, nullptr, "RequestLinkDevice"}, | ||
| 13 | {1, nullptr, "RequestCleanupAllPreInstalledApplications"}, | ||
| 14 | {2, nullptr, "RequestCleanupPreInstalledApplication"}, | ||
| 15 | {3, nullptr, "RequestSyncRights"}, | ||
| 16 | {4, nullptr, "RequestUnlinkDevice"}, | ||
| 17 | {5, nullptr, "RequestRevokeAllELicense"}, | ||
| 18 | {6, nullptr, "RequestSyncRightsBasedOnAssignedELicenses"}, | ||
| 19 | }; | ||
| 20 | // clang-format on | ||
| 21 | |||
| 22 | RegisterHandlers(functions); | ||
| 23 | } | ||
| 24 | |||
| 25 | IECommerceInterface::~IECommerceInterface() = default; | ||
| 26 | |||
| 27 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/ecommerce_interface.h b/src/core/hle/service/ns/ecommerce_interface.h new file mode 100644 index 000000000..4352101f4 --- /dev/null +++ b/src/core/hle/service/ns/ecommerce_interface.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::NS { | ||
| 9 | |||
| 10 | class IECommerceInterface final : public ServiceFramework<IECommerceInterface> { | ||
| 11 | public: | ||
| 12 | explicit IECommerceInterface(Core::System& system_); | ||
| 13 | ~IECommerceInterface() override; | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/factory_reset_interface.cpp b/src/core/hle/service/ns/factory_reset_interface.cpp new file mode 100644 index 000000000..fd5cf7e1f --- /dev/null +++ b/src/core/hle/service/ns/factory_reset_interface.cpp | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/ns/factory_reset_interface.h" | ||
| 5 | |||
| 6 | namespace Service::NS { | ||
| 7 | |||
| 8 | IFactoryResetInterface::IFactoryResetInterface(Core::System& system_) | ||
| 9 | : ServiceFramework{system_, "IFactoryResetInterface"} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {100, nullptr, "ResetToFactorySettings"}, | ||
| 13 | {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, | ||
| 14 | {102, nullptr, "ResetToFactorySettingsForRefurbishment"}, | ||
| 15 | {103, nullptr, "ResetToFactorySettingsWithPlatformRegion"}, | ||
| 16 | {104, nullptr, "ResetToFactorySettingsWithPlatformRegionAuthentication"}, | ||
| 17 | {105, nullptr, "RequestResetToFactorySettingsSecurely"}, | ||
| 18 | {106, nullptr, "RequestResetToFactorySettingsWithPlatformRegionAuthenticationSecurely"}, | ||
| 19 | }; | ||
| 20 | // clang-format on | ||
| 21 | |||
| 22 | RegisterHandlers(functions); | ||
| 23 | } | ||
| 24 | |||
| 25 | IFactoryResetInterface::~IFactoryResetInterface() = default; | ||
| 26 | |||
| 27 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/factory_reset_interface.h b/src/core/hle/service/ns/factory_reset_interface.h new file mode 100644 index 000000000..50d125123 --- /dev/null +++ b/src/core/hle/service/ns/factory_reset_interface.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::NS { | ||
| 9 | |||
| 10 | class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> { | ||
| 11 | public: | ||
| 12 | explicit IFactoryResetInterface(Core::System& system_); | ||
| 13 | ~IFactoryResetInterface() override; | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index 19c3ff01b..8402e83cb 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp | |||
| @@ -1,893 +1,38 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "common/logging/log.h" | 4 | #include "core/hle/service/ns/develop_interface.h" |
| 5 | #include "common/settings.h" | ||
| 6 | #include "core/arm/debug.h" | ||
| 7 | #include "core/core.h" | ||
| 8 | #include "core/file_sys/control_metadata.h" | ||
| 9 | #include "core/file_sys/patch_manager.h" | ||
| 10 | #include "core/file_sys/vfs/vfs.h" | ||
| 11 | #include "core/hle/service/filesystem/filesystem.h" | ||
| 12 | #include "core/hle/service/glue/glue_manager.h" | ||
| 13 | #include "core/hle/service/ipc_helpers.h" | ||
| 14 | #include "core/hle/service/ns/errors.h" | ||
| 15 | #include "core/hle/service/ns/iplatform_service_manager.h" | ||
| 16 | #include "core/hle/service/ns/language.h" | ||
| 17 | #include "core/hle/service/ns/ns.h" | 5 | #include "core/hle/service/ns/ns.h" |
| 18 | #include "core/hle/service/ns/pdm_qry.h" | 6 | #include "core/hle/service/ns/platform_service_manager.h" |
| 7 | #include "core/hle/service/ns/query_service.h" | ||
| 8 | #include "core/hle/service/ns/service_getter_interface.h" | ||
| 9 | #include "core/hle/service/ns/system_update_interface.h" | ||
| 10 | #include "core/hle/service/ns/vulnerability_manager_interface.h" | ||
| 19 | #include "core/hle/service/server_manager.h" | 11 | #include "core/hle/service/server_manager.h" |
| 20 | #include "core/hle/service/set/settings_server.h" | ||
| 21 | 12 | ||
| 22 | namespace Service::NS { | 13 | namespace Service::NS { |
| 23 | 14 | ||
| 24 | IAccountProxyInterface::IAccountProxyInterface(Core::System& system_) | ||
| 25 | : ServiceFramework{system_, "IAccountProxyInterface"} { | ||
| 26 | // clang-format off | ||
| 27 | static const FunctionInfo functions[] = { | ||
| 28 | {0, nullptr, "CreateUserAccount"}, | ||
| 29 | }; | ||
| 30 | // clang-format on | ||
| 31 | |||
| 32 | RegisterHandlers(functions); | ||
| 33 | } | ||
| 34 | |||
| 35 | IAccountProxyInterface::~IAccountProxyInterface() = default; | ||
| 36 | |||
| 37 | IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_) | ||
| 38 | : ServiceFramework{system_, "IApplicationManagerInterface"} { | ||
| 39 | // clang-format off | ||
| 40 | static const FunctionInfo functions[] = { | ||
| 41 | {0, nullptr, "ListApplicationRecord"}, | ||
| 42 | {1, nullptr, "GenerateApplicationRecordCount"}, | ||
| 43 | {2, nullptr, "GetApplicationRecordUpdateSystemEvent"}, | ||
| 44 | {3, nullptr, "GetApplicationViewDeprecated"}, | ||
| 45 | {4, nullptr, "DeleteApplicationEntity"}, | ||
| 46 | {5, nullptr, "DeleteApplicationCompletely"}, | ||
| 47 | {6, nullptr, "IsAnyApplicationEntityRedundant"}, | ||
| 48 | {7, nullptr, "DeleteRedundantApplicationEntity"}, | ||
| 49 | {8, nullptr, "IsApplicationEntityMovable"}, | ||
| 50 | {9, nullptr, "MoveApplicationEntity"}, | ||
| 51 | {11, nullptr, "CalculateApplicationOccupiedSize"}, | ||
| 52 | {16, nullptr, "PushApplicationRecord"}, | ||
| 53 | {17, nullptr, "ListApplicationRecordContentMeta"}, | ||
| 54 | {19, nullptr, "LaunchApplicationOld"}, | ||
| 55 | {21, nullptr, "GetApplicationContentPath"}, | ||
| 56 | {22, nullptr, "TerminateApplication"}, | ||
| 57 | {23, nullptr, "ResolveApplicationContentPath"}, | ||
| 58 | {26, nullptr, "BeginInstallApplication"}, | ||
| 59 | {27, nullptr, "DeleteApplicationRecord"}, | ||
| 60 | {30, nullptr, "RequestApplicationUpdateInfo"}, | ||
| 61 | {31, nullptr, "Unknown31"}, | ||
| 62 | {32, nullptr, "CancelApplicationDownload"}, | ||
| 63 | {33, nullptr, "ResumeApplicationDownload"}, | ||
| 64 | {35, nullptr, "UpdateVersionList"}, | ||
| 65 | {36, nullptr, "PushLaunchVersion"}, | ||
| 66 | {37, nullptr, "ListRequiredVersion"}, | ||
| 67 | {38, nullptr, "CheckApplicationLaunchVersion"}, | ||
| 68 | {39, nullptr, "CheckApplicationLaunchRights"}, | ||
| 69 | {40, nullptr, "GetApplicationLogoData"}, | ||
| 70 | {41, nullptr, "CalculateApplicationDownloadRequiredSize"}, | ||
| 71 | {42, nullptr, "CleanupSdCard"}, | ||
| 72 | {43, nullptr, "CheckSdCardMountStatus"}, | ||
| 73 | {44, nullptr, "GetSdCardMountStatusChangedEvent"}, | ||
| 74 | {45, nullptr, "GetGameCardAttachmentEvent"}, | ||
| 75 | {46, nullptr, "GetGameCardAttachmentInfo"}, | ||
| 76 | {47, nullptr, "GetTotalSpaceSize"}, | ||
| 77 | {48, nullptr, "GetFreeSpaceSize"}, | ||
| 78 | {49, nullptr, "GetSdCardRemovedEvent"}, | ||
| 79 | {52, nullptr, "GetGameCardUpdateDetectionEvent"}, | ||
| 80 | {53, nullptr, "DisableApplicationAutoDelete"}, | ||
| 81 | {54, nullptr, "EnableApplicationAutoDelete"}, | ||
| 82 | {55, &IApplicationManagerInterface::GetApplicationDesiredLanguage, "GetApplicationDesiredLanguage"}, | ||
| 83 | {56, nullptr, "SetApplicationTerminateResult"}, | ||
| 84 | {57, nullptr, "ClearApplicationTerminateResult"}, | ||
| 85 | {58, nullptr, "GetLastSdCardMountUnexpectedResult"}, | ||
| 86 | {59, &IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode, "ConvertApplicationLanguageToLanguageCode"}, | ||
| 87 | {60, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, | ||
| 88 | {61, nullptr, "GetBackgroundDownloadStressTaskInfo"}, | ||
| 89 | {62, nullptr, "GetGameCardStopper"}, | ||
| 90 | {63, nullptr, "IsSystemProgramInstalled"}, | ||
| 91 | {64, nullptr, "StartApplyDeltaTask"}, | ||
| 92 | {65, nullptr, "GetRequestServerStopper"}, | ||
| 93 | {66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"}, | ||
| 94 | {67, nullptr, "CancelApplicationApplyDelta"}, | ||
| 95 | {68, nullptr, "ResumeApplicationApplyDelta"}, | ||
| 96 | {69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"}, | ||
| 97 | {70, nullptr, "ResumeAll"}, | ||
| 98 | {71, nullptr, "GetStorageSize"}, | ||
| 99 | {80, nullptr, "RequestDownloadApplication"}, | ||
| 100 | {81, nullptr, "RequestDownloadAddOnContent"}, | ||
| 101 | {82, nullptr, "DownloadApplication"}, | ||
| 102 | {83, nullptr, "CheckApplicationResumeRights"}, | ||
| 103 | {84, nullptr, "GetDynamicCommitEvent"}, | ||
| 104 | {85, nullptr, "RequestUpdateApplication2"}, | ||
| 105 | {86, nullptr, "EnableApplicationCrashReport"}, | ||
| 106 | {87, nullptr, "IsApplicationCrashReportEnabled"}, | ||
| 107 | {90, nullptr, "BoostSystemMemoryResourceLimit"}, | ||
| 108 | {91, nullptr, "DeprecatedLaunchApplication"}, | ||
| 109 | {92, nullptr, "GetRunningApplicationProgramId"}, | ||
| 110 | {93, nullptr, "GetMainApplicationProgramIndex"}, | ||
| 111 | {94, nullptr, "LaunchApplication"}, | ||
| 112 | {95, nullptr, "GetApplicationLaunchInfo"}, | ||
| 113 | {96, nullptr, "AcquireApplicationLaunchInfo"}, | ||
| 114 | {97, nullptr, "GetMainApplicationProgramIndexByApplicationLaunchInfo"}, | ||
| 115 | {98, nullptr, "EnableApplicationAllThreadDumpOnCrash"}, | ||
| 116 | {99, nullptr, "LaunchDevMenu"}, | ||
| 117 | {100, nullptr, "ResetToFactorySettings"}, | ||
| 118 | {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, | ||
| 119 | {102, nullptr, "ResetToFactorySettingsForRefurbishment"}, | ||
| 120 | {103, nullptr, "ResetToFactorySettingsWithPlatformRegion"}, | ||
| 121 | {104, nullptr, "ResetToFactorySettingsWithPlatformRegionAuthentication"}, | ||
| 122 | {105, nullptr, "RequestResetToFactorySettingsSecurely"}, | ||
| 123 | {106, nullptr, "RequestResetToFactorySettingsWithPlatformRegionAuthenticationSecurely"}, | ||
| 124 | {200, nullptr, "CalculateUserSaveDataStatistics"}, | ||
| 125 | {201, nullptr, "DeleteUserSaveDataAll"}, | ||
| 126 | {210, nullptr, "DeleteUserSystemSaveData"}, | ||
| 127 | {211, nullptr, "DeleteSaveData"}, | ||
| 128 | {220, nullptr, "UnregisterNetworkServiceAccount"}, | ||
| 129 | {221, nullptr, "UnregisterNetworkServiceAccountWithUserSaveDataDeletion"}, | ||
| 130 | {300, nullptr, "GetApplicationShellEvent"}, | ||
| 131 | {301, nullptr, "PopApplicationShellEventInfo"}, | ||
| 132 | {302, nullptr, "LaunchLibraryApplet"}, | ||
| 133 | {303, nullptr, "TerminateLibraryApplet"}, | ||
| 134 | {304, nullptr, "LaunchSystemApplet"}, | ||
| 135 | {305, nullptr, "TerminateSystemApplet"}, | ||
| 136 | {306, nullptr, "LaunchOverlayApplet"}, | ||
| 137 | {307, nullptr, "TerminateOverlayApplet"}, | ||
| 138 | {400, &IApplicationManagerInterface::GetApplicationControlData, "GetApplicationControlData"}, | ||
| 139 | {401, nullptr, "InvalidateAllApplicationControlCache"}, | ||
| 140 | {402, nullptr, "RequestDownloadApplicationControlData"}, | ||
| 141 | {403, nullptr, "GetMaxApplicationControlCacheCount"}, | ||
| 142 | {404, nullptr, "InvalidateApplicationControlCache"}, | ||
| 143 | {405, nullptr, "ListApplicationControlCacheEntryInfo"}, | ||
| 144 | {406, nullptr, "GetApplicationControlProperty"}, | ||
| 145 | {407, nullptr, "ListApplicationTitle"}, | ||
| 146 | {408, nullptr, "ListApplicationIcon"}, | ||
| 147 | {502, nullptr, "RequestCheckGameCardRegistration"}, | ||
| 148 | {503, nullptr, "RequestGameCardRegistrationGoldPoint"}, | ||
| 149 | {504, nullptr, "RequestRegisterGameCard"}, | ||
| 150 | {505, nullptr, "GetGameCardMountFailureEvent"}, | ||
| 151 | {506, nullptr, "IsGameCardInserted"}, | ||
| 152 | {507, nullptr, "EnsureGameCardAccess"}, | ||
| 153 | {508, nullptr, "GetLastGameCardMountFailureResult"}, | ||
| 154 | {509, nullptr, "ListApplicationIdOnGameCard"}, | ||
| 155 | {510, nullptr, "GetGameCardPlatformRegion"}, | ||
| 156 | {600, nullptr, "CountApplicationContentMeta"}, | ||
| 157 | {601, nullptr, "ListApplicationContentMetaStatus"}, | ||
| 158 | {602, nullptr, "ListAvailableAddOnContent"}, | ||
| 159 | {603, nullptr, "GetOwnedApplicationContentMetaStatus"}, | ||
| 160 | {604, nullptr, "RegisterContentsExternalKey"}, | ||
| 161 | {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"}, | ||
| 162 | {606, nullptr, "GetContentMetaStorage"}, | ||
| 163 | {607, nullptr, "ListAvailableAddOnContent"}, | ||
| 164 | {609, nullptr, "ListAvailabilityAssuredAddOnContent"}, | ||
| 165 | {610, nullptr, "GetInstalledContentMetaStorage"}, | ||
| 166 | {611, nullptr, "PrepareAddOnContent"}, | ||
| 167 | {700, nullptr, "PushDownloadTaskList"}, | ||
| 168 | {701, nullptr, "ClearTaskStatusList"}, | ||
| 169 | {702, nullptr, "RequestDownloadTaskList"}, | ||
| 170 | {703, nullptr, "RequestEnsureDownloadTask"}, | ||
| 171 | {704, nullptr, "ListDownloadTaskStatus"}, | ||
| 172 | {705, nullptr, "RequestDownloadTaskListData"}, | ||
| 173 | {800, nullptr, "RequestVersionList"}, | ||
| 174 | {801, nullptr, "ListVersionList"}, | ||
| 175 | {802, nullptr, "RequestVersionListData"}, | ||
| 176 | {900, nullptr, "GetApplicationRecord"}, | ||
| 177 | {901, nullptr, "GetApplicationRecordProperty"}, | ||
| 178 | {902, nullptr, "EnableApplicationAutoUpdate"}, | ||
| 179 | {903, nullptr, "DisableApplicationAutoUpdate"}, | ||
| 180 | {904, nullptr, "TouchApplication"}, | ||
| 181 | {905, nullptr, "RequestApplicationUpdate"}, | ||
| 182 | {906, nullptr, "IsApplicationUpdateRequested"}, | ||
| 183 | {907, nullptr, "WithdrawApplicationUpdateRequest"}, | ||
| 184 | {908, nullptr, "ListApplicationRecordInstalledContentMeta"}, | ||
| 185 | {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"}, | ||
| 186 | {910, nullptr, "HasApplicationRecord"}, | ||
| 187 | {911, nullptr, "SetPreInstalledApplication"}, | ||
| 188 | {912, nullptr, "ClearPreInstalledApplicationFlag"}, | ||
| 189 | {913, nullptr, "ListAllApplicationRecord"}, | ||
| 190 | {914, nullptr, "HideApplicationRecord"}, | ||
| 191 | {915, nullptr, "ShowApplicationRecord"}, | ||
| 192 | {916, nullptr, "IsApplicationAutoDeleteDisabled"}, | ||
| 193 | {1000, nullptr, "RequestVerifyApplicationDeprecated"}, | ||
| 194 | {1001, nullptr, "CorruptApplicationForDebug"}, | ||
| 195 | {1002, nullptr, "RequestVerifyAddOnContentsRights"}, | ||
| 196 | {1003, nullptr, "RequestVerifyApplication"}, | ||
| 197 | {1004, nullptr, "CorruptContentForDebug"}, | ||
| 198 | {1200, nullptr, "NeedsUpdateVulnerability"}, | ||
| 199 | {1300, nullptr, "IsAnyApplicationEntityInstalled"}, | ||
| 200 | {1301, nullptr, "DeleteApplicationContentEntities"}, | ||
| 201 | {1302, nullptr, "CleanupUnrecordedApplicationEntity"}, | ||
| 202 | {1303, nullptr, "CleanupAddOnContentsWithNoRights"}, | ||
| 203 | {1304, nullptr, "DeleteApplicationContentEntity"}, | ||
| 204 | {1305, nullptr, "TryDeleteRunningApplicationEntity"}, | ||
| 205 | {1306, nullptr, "TryDeleteRunningApplicationCompletely"}, | ||
| 206 | {1307, nullptr, "TryDeleteRunningApplicationContentEntities"}, | ||
| 207 | {1308, nullptr, "DeleteApplicationCompletelyForDebug"}, | ||
| 208 | {1309, nullptr, "CleanupUnavailableAddOnContents"}, | ||
| 209 | {1310, nullptr, "RequestMoveApplicationEntity"}, | ||
| 210 | {1311, nullptr, "EstimateSizeToMove"}, | ||
| 211 | {1312, nullptr, "HasMovableEntity"}, | ||
| 212 | {1313, nullptr, "CleanupOrphanContents"}, | ||
| 213 | {1314, nullptr, "CheckPreconditionSatisfiedToMove"}, | ||
| 214 | {1400, nullptr, "PrepareShutdown"}, | ||
| 215 | {1500, nullptr, "FormatSdCard"}, | ||
| 216 | {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"}, | ||
| 217 | {1502, nullptr, "GetLastSdCardFormatUnexpectedResult"}, | ||
| 218 | {1504, nullptr, "InsertSdCard"}, | ||
| 219 | {1505, nullptr, "RemoveSdCard"}, | ||
| 220 | {1506, nullptr, "GetSdCardStartupStatus"}, | ||
| 221 | {1600, nullptr, "GetSystemSeedForPseudoDeviceId"}, | ||
| 222 | {1601, nullptr, "ResetSystemSeedForPseudoDeviceId"}, | ||
| 223 | {1700, nullptr, "ListApplicationDownloadingContentMeta"}, | ||
| 224 | {1701, nullptr, "GetApplicationView"}, | ||
| 225 | {1702, nullptr, "GetApplicationDownloadTaskStatus"}, | ||
| 226 | {1703, nullptr, "GetApplicationViewDownloadErrorContext"}, | ||
| 227 | {1704, nullptr, "GetApplicationViewWithPromotionInfo"}, | ||
| 228 | {1705, nullptr, "IsPatchAutoDeletableApplication"}, | ||
| 229 | {1800, nullptr, "IsNotificationSetupCompleted"}, | ||
| 230 | {1801, nullptr, "GetLastNotificationInfoCount"}, | ||
| 231 | {1802, nullptr, "ListLastNotificationInfo"}, | ||
| 232 | {1803, nullptr, "ListNotificationTask"}, | ||
| 233 | {1900, nullptr, "IsActiveAccount"}, | ||
| 234 | {1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"}, | ||
| 235 | {1902, nullptr, "GetApplicationTicketInfo"}, | ||
| 236 | {1903, nullptr, "RequestDownloadApplicationPrepurchasedRightsForAccount"}, | ||
| 237 | {2000, nullptr, "GetSystemDeliveryInfo"}, | ||
| 238 | {2001, nullptr, "SelectLatestSystemDeliveryInfo"}, | ||
| 239 | {2002, nullptr, "VerifyDeliveryProtocolVersion"}, | ||
| 240 | {2003, nullptr, "GetApplicationDeliveryInfo"}, | ||
| 241 | {2004, nullptr, "HasAllContentsToDeliver"}, | ||
| 242 | {2005, nullptr, "CompareApplicationDeliveryInfo"}, | ||
| 243 | {2006, nullptr, "CanDeliverApplication"}, | ||
| 244 | {2007, nullptr, "ListContentMetaKeyToDeliverApplication"}, | ||
| 245 | {2008, nullptr, "NeedsSystemUpdateToDeliverApplication"}, | ||
| 246 | {2009, nullptr, "EstimateRequiredSize"}, | ||
| 247 | {2010, nullptr, "RequestReceiveApplication"}, | ||
| 248 | {2011, nullptr, "CommitReceiveApplication"}, | ||
| 249 | {2012, nullptr, "GetReceiveApplicationProgress"}, | ||
| 250 | {2013, nullptr, "RequestSendApplication"}, | ||
| 251 | {2014, nullptr, "GetSendApplicationProgress"}, | ||
| 252 | {2015, nullptr, "CompareSystemDeliveryInfo"}, | ||
| 253 | {2016, nullptr, "ListNotCommittedContentMeta"}, | ||
| 254 | {2017, nullptr, "CreateDownloadTask"}, | ||
| 255 | {2018, nullptr, "GetApplicationDeliveryInfoHash"}, | ||
| 256 | {2050, nullptr, "GetApplicationRightsOnClient"}, | ||
| 257 | {2051, nullptr, "InvalidateRightsIdCache"}, | ||
| 258 | {2100, nullptr, "GetApplicationTerminateResult"}, | ||
| 259 | {2101, nullptr, "GetRawApplicationTerminateResult"}, | ||
| 260 | {2150, nullptr, "CreateRightsEnvironment"}, | ||
| 261 | {2151, nullptr, "DestroyRightsEnvironment"}, | ||
| 262 | {2152, nullptr, "ActivateRightsEnvironment"}, | ||
| 263 | {2153, nullptr, "DeactivateRightsEnvironment"}, | ||
| 264 | {2154, nullptr, "ForceActivateRightsContextForExit"}, | ||
| 265 | {2155, nullptr, "UpdateRightsEnvironmentStatus"}, | ||
| 266 | {2156, nullptr, "CreateRightsEnvironmentForMicroApplication"}, | ||
| 267 | {2160, nullptr, "AddTargetApplicationToRightsEnvironment"}, | ||
| 268 | {2161, nullptr, "SetUsersToRightsEnvironment"}, | ||
| 269 | {2170, nullptr, "GetRightsEnvironmentStatus"}, | ||
| 270 | {2171, nullptr, "GetRightsEnvironmentStatusChangedEvent"}, | ||
| 271 | {2180, nullptr, "RequestExtendRightsInRightsEnvironment"}, | ||
| 272 | {2181, nullptr, "GetResultOfExtendRightsInRightsEnvironment"}, | ||
| 273 | {2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"}, | ||
| 274 | {2190, nullptr, "GetRightsEnvironmentHandleForApplication"}, | ||
| 275 | {2199, nullptr, "GetRightsEnvironmentCountForDebug"}, | ||
| 276 | {2200, nullptr, "GetGameCardApplicationCopyIdentifier"}, | ||
| 277 | {2201, nullptr, "GetInstalledApplicationCopyIdentifier"}, | ||
| 278 | {2250, nullptr, "RequestReportActiveELicence"}, | ||
| 279 | {2300, nullptr, "ListEventLog"}, | ||
| 280 | {2350, nullptr, "PerformAutoUpdateByApplicationId"}, | ||
| 281 | {2351, nullptr, "RequestNoDownloadRightsErrorResolution"}, | ||
| 282 | {2352, nullptr, "RequestResolveNoDownloadRightsError"}, | ||
| 283 | {2353, nullptr, "GetApplicationDownloadTaskInfo"}, | ||
| 284 | {2354, nullptr, "PrioritizeApplicationBackgroundTask"}, | ||
| 285 | {2355, nullptr, "PreferStorageEfficientUpdate"}, | ||
| 286 | {2356, nullptr, "RequestStorageEfficientUpdatePreferable"}, | ||
| 287 | {2357, nullptr, "EnableMultiCoreDownload"}, | ||
| 288 | {2358, nullptr, "DisableMultiCoreDownload"}, | ||
| 289 | {2359, nullptr, "IsMultiCoreDownloadEnabled"}, | ||
| 290 | {2400, nullptr, "GetPromotionInfo"}, | ||
| 291 | {2401, nullptr, "CountPromotionInfo"}, | ||
| 292 | {2402, nullptr, "ListPromotionInfo"}, | ||
| 293 | {2403, nullptr, "ImportPromotionJsonForDebug"}, | ||
| 294 | {2404, nullptr, "ClearPromotionInfoForDebug"}, | ||
| 295 | {2500, nullptr, "ConfirmAvailableTime"}, | ||
| 296 | {2510, nullptr, "CreateApplicationResource"}, | ||
| 297 | {2511, nullptr, "GetApplicationResource"}, | ||
| 298 | {2513, nullptr, "LaunchMicroApplication"}, | ||
| 299 | {2514, nullptr, "ClearTaskOfAsyncTaskManager"}, | ||
| 300 | {2515, nullptr, "CleanupAllPlaceHolderAndFragmentsIfNoTask"}, | ||
| 301 | {2516, nullptr, "EnsureApplicationCertificate"}, | ||
| 302 | {2517, nullptr, "CreateApplicationInstance"}, | ||
| 303 | {2518, nullptr, "UpdateQualificationForDebug"}, | ||
| 304 | {2519, nullptr, "IsQualificationTransitionSupported"}, | ||
| 305 | {2520, nullptr, "IsQualificationTransitionSupportedByProcessId"}, | ||
| 306 | {2521, nullptr, "GetRightsUserChangedEvent"}, | ||
| 307 | {2522, nullptr, "IsRomRedirectionAvailable"}, | ||
| 308 | {2800, nullptr, "GetApplicationIdOfPreomia"}, | ||
| 309 | {3000, nullptr, "RegisterDeviceLockKey"}, | ||
| 310 | {3001, nullptr, "UnregisterDeviceLockKey"}, | ||
| 311 | {3002, nullptr, "VerifyDeviceLockKey"}, | ||
| 312 | {3003, nullptr, "HideApplicationIcon"}, | ||
| 313 | {3004, nullptr, "ShowApplicationIcon"}, | ||
| 314 | {3005, nullptr, "HideApplicationTitle"}, | ||
| 315 | {3006, nullptr, "ShowApplicationTitle"}, | ||
| 316 | {3007, nullptr, "EnableGameCard"}, | ||
| 317 | {3008, nullptr, "DisableGameCard"}, | ||
| 318 | {3009, nullptr, "EnableLocalContentShare"}, | ||
| 319 | {3010, nullptr, "DisableLocalContentShare"}, | ||
| 320 | {3011, nullptr, "IsApplicationIconHidden"}, | ||
| 321 | {3012, nullptr, "IsApplicationTitleHidden"}, | ||
| 322 | {3013, nullptr, "IsGameCardEnabled"}, | ||
| 323 | {3014, nullptr, "IsLocalContentShareEnabled"}, | ||
| 324 | {3050, nullptr, "ListAssignELicenseTaskResult"}, | ||
| 325 | {9999, nullptr, "GetApplicationCertificate"}, | ||
| 326 | }; | ||
| 327 | // clang-format on | ||
| 328 | |||
| 329 | RegisterHandlers(functions); | ||
| 330 | } | ||
| 331 | |||
| 332 | IApplicationManagerInterface::~IApplicationManagerInterface() = default; | ||
| 333 | |||
| 334 | void IApplicationManagerInterface::GetApplicationControlData(HLERequestContext& ctx) { | ||
| 335 | IPC::RequestParser rp{ctx}; | ||
| 336 | const auto flag = rp.PopRaw<u64>(); | ||
| 337 | LOG_DEBUG(Service_NS, "called with flag={:016X}", flag); | ||
| 338 | |||
| 339 | const auto title_id = rp.PopRaw<u64>(); | ||
| 340 | |||
| 341 | const auto size = ctx.GetWriteBufferSize(); | ||
| 342 | |||
| 343 | const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), | ||
| 344 | system.GetContentProvider()}; | ||
| 345 | const auto control = pm.GetControlMetadata(); | ||
| 346 | |||
| 347 | std::vector<u8> out; | ||
| 348 | |||
| 349 | if (control.first != nullptr) { | ||
| 350 | if (size < 0x4000) { | ||
| 351 | LOG_ERROR(Service_NS, | ||
| 352 | "output buffer is too small! (actual={:016X}, expected_min=0x4000)", size); | ||
| 353 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 354 | // TODO(DarkLordZach): Find a better error code for this. | ||
| 355 | rb.Push(ResultUnknown); | ||
| 356 | return; | ||
| 357 | } | ||
| 358 | |||
| 359 | out.resize(0x4000); | ||
| 360 | const auto bytes = control.first->GetRawBytes(); | ||
| 361 | std::memcpy(out.data(), bytes.data(), bytes.size()); | ||
| 362 | } else { | ||
| 363 | LOG_WARNING(Service_NS, "missing NACP data for title_id={:016X}, defaulting to zeros.", | ||
| 364 | title_id); | ||
| 365 | out.resize(std::min<u64>(0x4000, size)); | ||
| 366 | } | ||
| 367 | |||
| 368 | if (control.second != nullptr) { | ||
| 369 | if (size < 0x4000 + control.second->GetSize()) { | ||
| 370 | LOG_ERROR(Service_NS, | ||
| 371 | "output buffer is too small! (actual={:016X}, expected_min={:016X})", size, | ||
| 372 | 0x4000 + control.second->GetSize()); | ||
| 373 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 374 | // TODO(DarkLordZach): Find a better error code for this. | ||
| 375 | rb.Push(ResultUnknown); | ||
| 376 | return; | ||
| 377 | } | ||
| 378 | |||
| 379 | out.resize(0x4000 + control.second->GetSize()); | ||
| 380 | control.second->Read(out.data() + 0x4000, control.second->GetSize()); | ||
| 381 | } else { | ||
| 382 | LOG_WARNING(Service_NS, "missing icon data for title_id={:016X}, defaulting to zeros.", | ||
| 383 | title_id); | ||
| 384 | } | ||
| 385 | |||
| 386 | ctx.WriteBuffer(out); | ||
| 387 | |||
| 388 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 389 | rb.Push(ResultSuccess); | ||
| 390 | rb.Push<u32>(static_cast<u32>(out.size())); | ||
| 391 | } | ||
| 392 | |||
| 393 | void IApplicationManagerInterface::GetApplicationDesiredLanguage(HLERequestContext& ctx) { | ||
| 394 | IPC::RequestParser rp{ctx}; | ||
| 395 | const auto supported_languages = rp.Pop<u32>(); | ||
| 396 | |||
| 397 | u8 desired_language{}; | ||
| 398 | const auto res = GetApplicationDesiredLanguage(&desired_language, supported_languages); | ||
| 399 | if (res == ResultSuccess) { | ||
| 400 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 401 | rb.Push(ResultSuccess); | ||
| 402 | rb.Push<u32>(desired_language); | ||
| 403 | } else { | ||
| 404 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 405 | rb.Push(res); | ||
| 406 | } | ||
| 407 | } | ||
| 408 | |||
| 409 | Result IApplicationManagerInterface::GetApplicationDesiredLanguage(u8* out_desired_language, | ||
| 410 | const u32 supported_languages) { | ||
| 411 | LOG_DEBUG(Service_NS, "called with supported_languages={:08X}", supported_languages); | ||
| 412 | |||
| 413 | // Get language code from settings | ||
| 414 | const auto language_code = | ||
| 415 | Set::GetLanguageCodeFromIndex(static_cast<s32>(Settings::values.language_index.GetValue())); | ||
| 416 | |||
| 417 | // Convert to application language, get priority list | ||
| 418 | const auto application_language = ConvertToApplicationLanguage(language_code); | ||
| 419 | if (application_language == std::nullopt) { | ||
| 420 | LOG_ERROR(Service_NS, "Could not convert application language! language_code={}", | ||
| 421 | language_code); | ||
| 422 | return Service::NS::ResultApplicationLanguageNotFound; | ||
| 423 | } | ||
| 424 | const auto priority_list = GetApplicationLanguagePriorityList(*application_language); | ||
| 425 | if (!priority_list) { | ||
| 426 | LOG_ERROR(Service_NS, | ||
| 427 | "Could not find application language priorities! application_language={}", | ||
| 428 | *application_language); | ||
| 429 | return Service::NS::ResultApplicationLanguageNotFound; | ||
| 430 | } | ||
| 431 | |||
| 432 | // Try to find a valid language. | ||
| 433 | for (const auto lang : *priority_list) { | ||
| 434 | const auto supported_flag = GetSupportedLanguageFlag(lang); | ||
| 435 | if (supported_languages == 0 || (supported_languages & supported_flag) == supported_flag) { | ||
| 436 | *out_desired_language = static_cast<u8>(lang); | ||
| 437 | return ResultSuccess; | ||
| 438 | } | ||
| 439 | } | ||
| 440 | |||
| 441 | LOG_ERROR(Service_NS, "Could not find a valid language! supported_languages={:08X}", | ||
| 442 | supported_languages); | ||
| 443 | return Service::NS::ResultApplicationLanguageNotFound; | ||
| 444 | } | ||
| 445 | |||
| 446 | void IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode( | ||
| 447 | HLERequestContext& ctx) { | ||
| 448 | IPC::RequestParser rp{ctx}; | ||
| 449 | const auto application_language = rp.Pop<u8>(); | ||
| 450 | |||
| 451 | u64 language_code{}; | ||
| 452 | const auto res = ConvertApplicationLanguageToLanguageCode(&language_code, application_language); | ||
| 453 | if (res == ResultSuccess) { | ||
| 454 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 455 | rb.Push(ResultSuccess); | ||
| 456 | rb.Push(language_code); | ||
| 457 | } else { | ||
| 458 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 459 | rb.Push(res); | ||
| 460 | } | ||
| 461 | } | ||
| 462 | |||
| 463 | Result IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode( | ||
| 464 | u64* out_language_code, u8 application_language) { | ||
| 465 | const auto language_code = | ||
| 466 | ConvertToLanguageCode(static_cast<ApplicationLanguage>(application_language)); | ||
| 467 | if (language_code == std::nullopt) { | ||
| 468 | LOG_ERROR(Service_NS, "Language not found! application_language={}", application_language); | ||
| 469 | return Service::NS::ResultApplicationLanguageNotFound; | ||
| 470 | } | ||
| 471 | |||
| 472 | *out_language_code = static_cast<u64>(*language_code); | ||
| 473 | return ResultSuccess; | ||
| 474 | } | ||
| 475 | |||
| 476 | IApplicationVersionInterface::IApplicationVersionInterface(Core::System& system_) | ||
| 477 | : ServiceFramework{system_, "IApplicationVersionInterface"} { | ||
| 478 | // clang-format off | ||
| 479 | static const FunctionInfo functions[] = { | ||
| 480 | {0, nullptr, "GetLaunchRequiredVersion"}, | ||
| 481 | {1, nullptr, "UpgradeLaunchRequiredVersion"}, | ||
| 482 | {35, nullptr, "UpdateVersionList"}, | ||
| 483 | {36, nullptr, "PushLaunchVersion"}, | ||
| 484 | {37, nullptr, "ListRequiredVersion"}, | ||
| 485 | {800, nullptr, "RequestVersionList"}, | ||
| 486 | {801, nullptr, "ListVersionList"}, | ||
| 487 | {802, nullptr, "RequestVersionListData"}, | ||
| 488 | {900, nullptr, "ImportAutoUpdatePolicyJsonForDebug"}, | ||
| 489 | {901, nullptr, "ListDefaultAutoUpdatePolicy"}, | ||
| 490 | {902, nullptr, "ListAutoUpdatePolicyForSpecificApplication"}, | ||
| 491 | {1000, nullptr, "PerformAutoUpdate"}, | ||
| 492 | {1001, nullptr, "ListAutoUpdateSchedule"}, | ||
| 493 | }; | ||
| 494 | // clang-format on | ||
| 495 | |||
| 496 | RegisterHandlers(functions); | ||
| 497 | } | ||
| 498 | |||
| 499 | IApplicationVersionInterface::~IApplicationVersionInterface() = default; | ||
| 500 | |||
| 501 | IContentManagementInterface::IContentManagementInterface(Core::System& system_) | ||
| 502 | : ServiceFramework{system_, "IContentManagementInterface"} { | ||
| 503 | // clang-format off | ||
| 504 | static const FunctionInfo functions[] = { | ||
| 505 | {11, nullptr, "CalculateApplicationOccupiedSize"}, | ||
| 506 | {43, nullptr, "CheckSdCardMountStatus"}, | ||
| 507 | {47, &IContentManagementInterface::GetTotalSpaceSize, "GetTotalSpaceSize"}, | ||
| 508 | {48, &IContentManagementInterface::GetFreeSpaceSize, "GetFreeSpaceSize"}, | ||
| 509 | {600, nullptr, "CountApplicationContentMeta"}, | ||
| 510 | {601, nullptr, "ListApplicationContentMetaStatus"}, | ||
| 511 | {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"}, | ||
| 512 | {607, nullptr, "IsAnyApplicationRunning"}, | ||
| 513 | }; | ||
| 514 | // clang-format on | ||
| 515 | |||
| 516 | RegisterHandlers(functions); | ||
| 517 | } | ||
| 518 | |||
| 519 | IContentManagementInterface::~IContentManagementInterface() = default; | ||
| 520 | |||
| 521 | void IContentManagementInterface::GetTotalSpaceSize(HLERequestContext& ctx) { | ||
| 522 | IPC::RequestParser rp{ctx}; | ||
| 523 | const auto storage{rp.PopEnum<FileSys::StorageId>()}; | ||
| 524 | |||
| 525 | LOG_INFO(Service_Capture, "called, storage={}", storage); | ||
| 526 | |||
| 527 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 528 | rb.Push(ResultSuccess); | ||
| 529 | rb.Push<u64>(system.GetFileSystemController().GetTotalSpaceSize(storage)); | ||
| 530 | } | ||
| 531 | |||
| 532 | void IContentManagementInterface::GetFreeSpaceSize(HLERequestContext& ctx) { | ||
| 533 | IPC::RequestParser rp{ctx}; | ||
| 534 | const auto storage{rp.PopEnum<FileSys::StorageId>()}; | ||
| 535 | |||
| 536 | LOG_INFO(Service_Capture, "called, storage={}", storage); | ||
| 537 | |||
| 538 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 539 | rb.Push(ResultSuccess); | ||
| 540 | rb.Push<u64>(system.GetFileSystemController().GetFreeSpaceSize(storage)); | ||
| 541 | } | ||
| 542 | |||
| 543 | IDocumentInterface::IDocumentInterface(Core::System& system_) | ||
| 544 | : ServiceFramework{system_, "IDocumentInterface"} { | ||
| 545 | // clang-format off | ||
| 546 | static const FunctionInfo functions[] = { | ||
| 547 | {21, nullptr, "GetApplicationContentPath"}, | ||
| 548 | {23, &IDocumentInterface::ResolveApplicationContentPath, "ResolveApplicationContentPath"}, | ||
| 549 | {92, &IDocumentInterface::GetRunningApplicationProgramId, "GetRunningApplicationProgramId"}, | ||
| 550 | }; | ||
| 551 | // clang-format on | ||
| 552 | |||
| 553 | RegisterHandlers(functions); | ||
| 554 | } | ||
| 555 | |||
| 556 | IDocumentInterface::~IDocumentInterface() = default; | ||
| 557 | |||
| 558 | void IDocumentInterface::ResolveApplicationContentPath(HLERequestContext& ctx) { | ||
| 559 | struct ContentPath { | ||
| 560 | u8 file_system_proxy_type; | ||
| 561 | u64 program_id; | ||
| 562 | }; | ||
| 563 | static_assert(sizeof(ContentPath) == 0x10, "ContentPath has wrong size"); | ||
| 564 | |||
| 565 | IPC::RequestParser rp{ctx}; | ||
| 566 | auto content_path = rp.PopRaw<ContentPath>(); | ||
| 567 | LOG_WARNING(Service_NS, "(STUBBED) called, file_system_proxy_type={}, program_id={:016X}", | ||
| 568 | content_path.file_system_proxy_type, content_path.program_id); | ||
| 569 | |||
| 570 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 571 | rb.Push(ResultSuccess); | ||
| 572 | } | ||
| 573 | |||
| 574 | void IDocumentInterface::GetRunningApplicationProgramId(HLERequestContext& ctx) { | ||
| 575 | IPC::RequestParser rp{ctx}; | ||
| 576 | const auto caller_program_id = rp.PopRaw<u64>(); | ||
| 577 | LOG_WARNING(Service_NS, "(STUBBED) called, caller_program_id={:016X}", caller_program_id); | ||
| 578 | |||
| 579 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 580 | rb.Push(ResultSuccess); | ||
| 581 | rb.Push<u64>(system.GetApplicationProcessProgramID()); | ||
| 582 | } | ||
| 583 | |||
| 584 | IDownloadTaskInterface::IDownloadTaskInterface(Core::System& system_) | ||
| 585 | : ServiceFramework{system_, "IDownloadTaskInterface"} { | ||
| 586 | // clang-format off | ||
| 587 | static const FunctionInfo functions[] = { | ||
| 588 | {701, nullptr, "ClearTaskStatusList"}, | ||
| 589 | {702, nullptr, "RequestDownloadTaskList"}, | ||
| 590 | {703, nullptr, "RequestEnsureDownloadTask"}, | ||
| 591 | {704, nullptr, "ListDownloadTaskStatus"}, | ||
| 592 | {705, nullptr, "RequestDownloadTaskListData"}, | ||
| 593 | {706, nullptr, "TryCommitCurrentApplicationDownloadTask"}, | ||
| 594 | {707, nullptr, "EnableAutoCommit"}, | ||
| 595 | {708, nullptr, "DisableAutoCommit"}, | ||
| 596 | {709, nullptr, "TriggerDynamicCommitEvent"}, | ||
| 597 | }; | ||
| 598 | // clang-format on | ||
| 599 | |||
| 600 | RegisterHandlers(functions); | ||
| 601 | } | ||
| 602 | |||
| 603 | IDownloadTaskInterface::~IDownloadTaskInterface() = default; | ||
| 604 | |||
| 605 | IECommerceInterface::IECommerceInterface(Core::System& system_) | ||
| 606 | : ServiceFramework{system_, "IECommerceInterface"} { | ||
| 607 | // clang-format off | ||
| 608 | static const FunctionInfo functions[] = { | ||
| 609 | {0, nullptr, "RequestLinkDevice"}, | ||
| 610 | {1, nullptr, "RequestCleanupAllPreInstalledApplications"}, | ||
| 611 | {2, nullptr, "RequestCleanupPreInstalledApplication"}, | ||
| 612 | {3, nullptr, "RequestSyncRights"}, | ||
| 613 | {4, nullptr, "RequestUnlinkDevice"}, | ||
| 614 | {5, nullptr, "RequestRevokeAllELicense"}, | ||
| 615 | {6, nullptr, "RequestSyncRightsBasedOnAssignedELicenses"}, | ||
| 616 | }; | ||
| 617 | // clang-format on | ||
| 618 | |||
| 619 | RegisterHandlers(functions); | ||
| 620 | } | ||
| 621 | |||
| 622 | IECommerceInterface::~IECommerceInterface() = default; | ||
| 623 | |||
| 624 | IFactoryResetInterface::IFactoryResetInterface(Core::System& system_) | ||
| 625 | : ServiceFramework{system_, "IFactoryResetInterface"} { | ||
| 626 | // clang-format off | ||
| 627 | static const FunctionInfo functions[] = { | ||
| 628 | {100, nullptr, "ResetToFactorySettings"}, | ||
| 629 | {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, | ||
| 630 | {102, nullptr, "ResetToFactorySettingsForRefurbishment"}, | ||
| 631 | {103, nullptr, "ResetToFactorySettingsWithPlatformRegion"}, | ||
| 632 | {104, nullptr, "ResetToFactorySettingsWithPlatformRegionAuthentication"}, | ||
| 633 | {105, nullptr, "RequestResetToFactorySettingsSecurely"}, | ||
| 634 | {106, nullptr, "RequestResetToFactorySettingsWithPlatformRegionAuthenticationSecurely"}, | ||
| 635 | }; | ||
| 636 | // clang-format on | ||
| 637 | |||
| 638 | RegisterHandlers(functions); | ||
| 639 | } | ||
| 640 | |||
| 641 | IFactoryResetInterface::~IFactoryResetInterface() = default; | ||
| 642 | |||
| 643 | IReadOnlyApplicationRecordInterface::IReadOnlyApplicationRecordInterface(Core::System& system_) | ||
| 644 | : ServiceFramework{system_, "IReadOnlyApplicationRecordInterface"} { | ||
| 645 | static const FunctionInfo functions[] = { | ||
| 646 | {0, &IReadOnlyApplicationRecordInterface::HasApplicationRecord, "HasApplicationRecord"}, | ||
| 647 | {1, nullptr, "NotifyApplicationFailure"}, | ||
| 648 | {2, &IReadOnlyApplicationRecordInterface::IsDataCorruptedResult, "IsDataCorruptedResult"}, | ||
| 649 | }; | ||
| 650 | // clang-format on | ||
| 651 | |||
| 652 | RegisterHandlers(functions); | ||
| 653 | } | ||
| 654 | |||
| 655 | IReadOnlyApplicationRecordInterface::~IReadOnlyApplicationRecordInterface() = default; | ||
| 656 | |||
| 657 | void IReadOnlyApplicationRecordInterface::HasApplicationRecord(HLERequestContext& ctx) { | ||
| 658 | IPC::RequestParser rp{ctx}; | ||
| 659 | const u64 program_id = rp.PopRaw<u64>(); | ||
| 660 | LOG_WARNING(Service_NS, "(STUBBED) called, program_id={:X}", program_id); | ||
| 661 | |||
| 662 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 663 | rb.Push(ResultSuccess); | ||
| 664 | rb.Push<u8>(1); | ||
| 665 | } | ||
| 666 | |||
| 667 | void IReadOnlyApplicationRecordInterface::IsDataCorruptedResult(HLERequestContext& ctx) { | ||
| 668 | IPC::RequestParser rp{ctx}; | ||
| 669 | const auto result = rp.PopRaw<Result>(); | ||
| 670 | LOG_WARNING(Service_NS, "(STUBBED) called, result={:#x}", result.GetInnerValue()); | ||
| 671 | |||
| 672 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 673 | rb.Push(ResultSuccess); | ||
| 674 | rb.Push<u8>(0); | ||
| 675 | } | ||
| 676 | |||
| 677 | IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterface( | ||
| 678 | Core::System& system_) | ||
| 679 | : ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} { | ||
| 680 | // clang-format off | ||
| 681 | static const FunctionInfo functions[] = { | ||
| 682 | {0, &IReadOnlyApplicationControlDataInterface::GetApplicationControlData, "GetApplicationControlData"}, | ||
| 683 | {1, nullptr, "GetApplicationDesiredLanguage"}, | ||
| 684 | {2, nullptr, "ConvertApplicationLanguageToLanguageCode"}, | ||
| 685 | {3, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, | ||
| 686 | {4, nullptr, "SelectApplicationDesiredLanguage"}, | ||
| 687 | }; | ||
| 688 | // clang-format on | ||
| 689 | |||
| 690 | RegisterHandlers(functions); | ||
| 691 | } | ||
| 692 | |||
| 693 | IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default; | ||
| 694 | |||
| 695 | void IReadOnlyApplicationControlDataInterface::GetApplicationControlData(HLERequestContext& ctx) { | ||
| 696 | enum class ApplicationControlSource : u8 { | ||
| 697 | CacheOnly, | ||
| 698 | Storage, | ||
| 699 | StorageOnly, | ||
| 700 | }; | ||
| 701 | |||
| 702 | struct RequestParameters { | ||
| 703 | ApplicationControlSource source; | ||
| 704 | u64 application_id; | ||
| 705 | }; | ||
| 706 | static_assert(sizeof(RequestParameters) == 0x10, "RequestParameters has incorrect size."); | ||
| 707 | |||
| 708 | IPC::RequestParser rp{ctx}; | ||
| 709 | std::vector<u8> nacp_data{}; | ||
| 710 | const auto parameters{rp.PopRaw<RequestParameters>()}; | ||
| 711 | const auto result = | ||
| 712 | system.GetARPManager().GetControlProperty(&nacp_data, parameters.application_id); | ||
| 713 | |||
| 714 | if (result == ResultSuccess) { | ||
| 715 | ctx.WriteBuffer(nacp_data.data(), nacp_data.size()); | ||
| 716 | } | ||
| 717 | |||
| 718 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 719 | rb.Push(result); | ||
| 720 | } | ||
| 721 | |||
| 722 | NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} { | ||
| 723 | // clang-format off | ||
| 724 | static const FunctionInfo functions[] = { | ||
| 725 | {7988, nullptr, "GetDynamicRightsInterface"}, | ||
| 726 | {7989, &NS::PushInterface<IReadOnlyApplicationControlDataInterface>, "GetReadOnlyApplicationControlDataInterface"}, | ||
| 727 | {7991, &NS::PushInterface<IReadOnlyApplicationRecordInterface>, "GetReadOnlyApplicationRecordInterface"}, | ||
| 728 | {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"}, | ||
| 729 | {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"}, | ||
| 730 | {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"}, | ||
| 731 | {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"}, | ||
| 732 | {7996, &NS::PushIApplicationManagerInterface, "GetApplicationManagerInterface"}, | ||
| 733 | {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"}, | ||
| 734 | {7998, &NS::PushInterface<IContentManagementInterface>, "GetContentManagementInterface"}, | ||
| 735 | {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"}, | ||
| 736 | }; | ||
| 737 | // clang-format on | ||
| 738 | |||
| 739 | RegisterHandlers(functions); | ||
| 740 | } | ||
| 741 | |||
| 742 | NS::~NS() = default; | ||
| 743 | |||
| 744 | std::shared_ptr<IApplicationManagerInterface> NS::GetApplicationManagerInterface() const { | ||
| 745 | return GetInterface<IApplicationManagerInterface>(system); | ||
| 746 | } | ||
| 747 | |||
| 748 | class NS_DEV final : public ServiceFramework<NS_DEV> { | ||
| 749 | public: | ||
| 750 | explicit NS_DEV(Core::System& system_) : ServiceFramework{system_, "ns:dev"} { | ||
| 751 | // clang-format off | ||
| 752 | static const FunctionInfo functions[] = { | ||
| 753 | {0, nullptr, "LaunchProgram"}, | ||
| 754 | {1, nullptr, "TerminateProcess"}, | ||
| 755 | {2, nullptr, "TerminateProgram"}, | ||
| 756 | {4, nullptr, "GetShellEvent"}, | ||
| 757 | {5, nullptr, "GetShellEventInfo"}, | ||
| 758 | {6, nullptr, "TerminateApplication"}, | ||
| 759 | {7, nullptr, "PrepareLaunchProgramFromHost"}, | ||
| 760 | {8, nullptr, "LaunchApplicationFromHost"}, | ||
| 761 | {9, nullptr, "LaunchApplicationWithStorageIdForDevelop"}, | ||
| 762 | {10, nullptr, "IsSystemMemoryResourceLimitBoosted"}, | ||
| 763 | {11, nullptr, "GetRunningApplicationProcessIdForDevelop"}, | ||
| 764 | {12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop"}, | ||
| 765 | {13, nullptr, "CreateApplicationResourceForDevelop"}, | ||
| 766 | {14, nullptr, "IsPreomiaForDevelop"}, | ||
| 767 | {15, nullptr, "GetApplicationProgramIdFromHost"}, | ||
| 768 | {16, nullptr, "RefreshCachedDebugValues"}, | ||
| 769 | {17, nullptr, "PrepareLaunchApplicationFromHost"}, | ||
| 770 | {18, nullptr, "GetLaunchEvent"}, | ||
| 771 | {19, nullptr, "GetLaunchResult"}, | ||
| 772 | }; | ||
| 773 | // clang-format on | ||
| 774 | |||
| 775 | RegisterHandlers(functions); | ||
| 776 | } | ||
| 777 | }; | ||
| 778 | |||
| 779 | class ISystemUpdateControl final : public ServiceFramework<ISystemUpdateControl> { | ||
| 780 | public: | ||
| 781 | explicit ISystemUpdateControl(Core::System& system_) | ||
| 782 | : ServiceFramework{system_, "ISystemUpdateControl"} { | ||
| 783 | // clang-format off | ||
| 784 | static const FunctionInfo functions[] = { | ||
| 785 | {0, nullptr, "HasDownloaded"}, | ||
| 786 | {1, nullptr, "RequestCheckLatestUpdate"}, | ||
| 787 | {2, nullptr, "RequestDownloadLatestUpdate"}, | ||
| 788 | {3, nullptr, "GetDownloadProgress"}, | ||
| 789 | {4, nullptr, "ApplyDownloadedUpdate"}, | ||
| 790 | {5, nullptr, "RequestPrepareCardUpdate"}, | ||
| 791 | {6, nullptr, "GetPrepareCardUpdateProgress"}, | ||
| 792 | {7, nullptr, "HasPreparedCardUpdate"}, | ||
| 793 | {8, nullptr, "ApplyCardUpdate"}, | ||
| 794 | {9, nullptr, "GetDownloadedEulaDataSize"}, | ||
| 795 | {10, nullptr, "GetDownloadedEulaData"}, | ||
| 796 | {11, nullptr, "SetupCardUpdate"}, | ||
| 797 | {12, nullptr, "GetPreparedCardUpdateEulaDataSize"}, | ||
| 798 | {13, nullptr, "GetPreparedCardUpdateEulaData"}, | ||
| 799 | {14, nullptr, "SetupCardUpdateViaSystemUpdater"}, | ||
| 800 | {15, nullptr, "HasReceived"}, | ||
| 801 | {16, nullptr, "RequestReceiveSystemUpdate"}, | ||
| 802 | {17, nullptr, "GetReceiveProgress"}, | ||
| 803 | {18, nullptr, "ApplyReceivedUpdate"}, | ||
| 804 | {19, nullptr, "GetReceivedEulaDataSize"}, | ||
| 805 | {20, nullptr, "GetReceivedEulaData"}, | ||
| 806 | {21, nullptr, "SetupToReceiveSystemUpdate"}, | ||
| 807 | {22, nullptr, "RequestCheckLatestUpdateIncludesRebootlessUpdate"}, | ||
| 808 | }; | ||
| 809 | // clang-format on | ||
| 810 | |||
| 811 | RegisterHandlers(functions); | ||
| 812 | } | ||
| 813 | }; | ||
| 814 | |||
| 815 | class NS_SU final : public ServiceFramework<NS_SU> { | ||
| 816 | public: | ||
| 817 | explicit NS_SU(Core::System& system_) : ServiceFramework{system_, "ns:su"} { | ||
| 818 | // clang-format off | ||
| 819 | static const FunctionInfo functions[] = { | ||
| 820 | {0, nullptr, "GetBackgroundNetworkUpdateState"}, | ||
| 821 | {1, &NS_SU::OpenSystemUpdateControl, "OpenSystemUpdateControl"}, | ||
| 822 | {2, nullptr, "NotifyExFatDriverRequired"}, | ||
| 823 | {3, nullptr, "ClearExFatDriverStatusForDebug"}, | ||
| 824 | {4, nullptr, "RequestBackgroundNetworkUpdate"}, | ||
| 825 | {5, nullptr, "NotifyBackgroundNetworkUpdate"}, | ||
| 826 | {6, nullptr, "NotifyExFatDriverDownloadedForDebug"}, | ||
| 827 | {9, nullptr, "GetSystemUpdateNotificationEventForContentDelivery"}, | ||
| 828 | {10, nullptr, "NotifySystemUpdateForContentDelivery"}, | ||
| 829 | {11, nullptr, "PrepareShutdown"}, | ||
| 830 | {12, nullptr, "Unknown12"}, | ||
| 831 | {13, nullptr, "Unknown13"}, | ||
| 832 | {14, nullptr, "Unknown14"}, | ||
| 833 | {15, nullptr, "Unknown15"}, | ||
| 834 | {16, nullptr, "DestroySystemUpdateTask"}, | ||
| 835 | {17, nullptr, "RequestSendSystemUpdate"}, | ||
| 836 | {18, nullptr, "GetSendSystemUpdateProgress"}, | ||
| 837 | }; | ||
| 838 | // clang-format on | ||
| 839 | |||
| 840 | RegisterHandlers(functions); | ||
| 841 | } | ||
| 842 | |||
| 843 | private: | ||
| 844 | void OpenSystemUpdateControl(HLERequestContext& ctx) { | ||
| 845 | LOG_DEBUG(Service_NS, "called"); | ||
| 846 | |||
| 847 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 848 | rb.Push(ResultSuccess); | ||
| 849 | rb.PushIpcInterface<ISystemUpdateControl>(system); | ||
| 850 | } | ||
| 851 | }; | ||
| 852 | |||
| 853 | class NS_VM final : public ServiceFramework<NS_VM> { | ||
| 854 | public: | ||
| 855 | explicit NS_VM(Core::System& system_) : ServiceFramework{system_, "ns:vm"} { | ||
| 856 | // clang-format off | ||
| 857 | static const FunctionInfo functions[] = { | ||
| 858 | {1200, &NS_VM::NeedsUpdateVulnerability, "NeedsUpdateVulnerability"}, | ||
| 859 | {1201, nullptr, "UpdateSafeSystemVersionForDebug"}, | ||
| 860 | {1202, nullptr, "GetSafeSystemVersion"}, | ||
| 861 | }; | ||
| 862 | // clang-format on | ||
| 863 | |||
| 864 | RegisterHandlers(functions); | ||
| 865 | } | ||
| 866 | |||
| 867 | private: | ||
| 868 | void NeedsUpdateVulnerability(HLERequestContext& ctx) { | ||
| 869 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 870 | |||
| 871 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 872 | rb.Push(ResultSuccess); | ||
| 873 | rb.Push(false); | ||
| 874 | } | ||
| 875 | }; | ||
| 876 | |||
| 877 | void LoopProcess(Core::System& system) { | 15 | void LoopProcess(Core::System& system) { |
| 878 | auto server_manager = std::make_unique<ServerManager>(system); | 16 | auto server_manager = std::make_unique<ServerManager>(system); |
| 879 | 17 | ||
| 880 | server_manager->RegisterNamedService("ns:am2", std::make_shared<NS>("ns:am2", system)); | 18 | server_manager->RegisterNamedService( |
| 881 | server_manager->RegisterNamedService("ns:ec", std::make_shared<NS>("ns:ec", system)); | 19 | "ns:am2", std::make_shared<IServiceGetterInterface>(system, "ns:am2")); |
| 882 | server_manager->RegisterNamedService("ns:rid", std::make_shared<NS>("ns:rid", system)); | 20 | server_manager->RegisterNamedService( |
| 883 | server_manager->RegisterNamedService("ns:rt", std::make_shared<NS>("ns:rt", system)); | 21 | "ns:ec", std::make_shared<IServiceGetterInterface>(system, "ns:ec")); |
| 884 | server_manager->RegisterNamedService("ns:web", std::make_shared<NS>("ns:web", system)); | 22 | server_manager->RegisterNamedService( |
| 885 | server_manager->RegisterNamedService("ns:ro", std::make_shared<NS>("ns:ro", system)); | 23 | "ns:rid", std::make_shared<IServiceGetterInterface>(system, "ns:rid")); |
| 886 | 24 | server_manager->RegisterNamedService( | |
| 887 | server_manager->RegisterNamedService("ns:dev", std::make_shared<NS_DEV>(system)); | 25 | "ns:rt", std::make_shared<IServiceGetterInterface>(system, "ns:rt")); |
| 888 | server_manager->RegisterNamedService("ns:su", std::make_shared<NS_SU>(system)); | 26 | server_manager->RegisterNamedService( |
| 889 | server_manager->RegisterNamedService("ns:vm", std::make_shared<NS_VM>(system)); | 27 | "ns:web", std::make_shared<IServiceGetterInterface>(system, "ns:web")); |
| 890 | server_manager->RegisterNamedService("pdm:qry", std::make_shared<PDM_QRY>(system)); | 28 | server_manager->RegisterNamedService( |
| 29 | "ns:ro", std::make_shared<IServiceGetterInterface>(system, "ns:ro")); | ||
| 30 | |||
| 31 | server_manager->RegisterNamedService("ns:dev", std::make_shared<IDevelopInterface>(system)); | ||
| 32 | server_manager->RegisterNamedService("ns:su", std::make_shared<ISystemUpdateInterface>(system)); | ||
| 33 | server_manager->RegisterNamedService("ns:vm", | ||
| 34 | std::make_shared<IVulnerabilityManagerInterface>(system)); | ||
| 35 | server_manager->RegisterNamedService("pdm:qry", std::make_shared<IQueryService>(system)); | ||
| 891 | 36 | ||
| 892 | server_manager->RegisterNamedService("pl:s", | 37 | server_manager->RegisterNamedService("pl:s", |
| 893 | std::make_shared<IPlatformServiceManager>(system, "pl:s")); | 38 | std::make_shared<IPlatformServiceManager>(system, "pl:s")); |
diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h index 9ee306ef9..f79b4ae3d 100644 --- a/src/core/hle/service/ns/ns.h +++ b/src/core/hle/service/ns/ns.h | |||
| @@ -3,141 +3,12 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Core { | 6 | namespace Core { |
| 9 | class System; | 7 | class System; |
| 10 | } | 8 | } |
| 11 | 9 | ||
| 12 | namespace Service { | 10 | namespace Service::NS { |
| 13 | |||
| 14 | namespace FileSystem { | ||
| 15 | class FileSystemController; | ||
| 16 | } // namespace FileSystem | ||
| 17 | |||
| 18 | namespace NS { | ||
| 19 | |||
| 20 | class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> { | ||
| 21 | public: | ||
| 22 | explicit IAccountProxyInterface(Core::System& system_); | ||
| 23 | ~IAccountProxyInterface() override; | ||
| 24 | }; | ||
| 25 | |||
| 26 | class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> { | ||
| 27 | public: | ||
| 28 | explicit IApplicationManagerInterface(Core::System& system_); | ||
| 29 | ~IApplicationManagerInterface() override; | ||
| 30 | |||
| 31 | Result GetApplicationDesiredLanguage(u8* out_desired_language, u32 supported_languages); | ||
| 32 | Result ConvertApplicationLanguageToLanguageCode(u64* out_language_code, | ||
| 33 | u8 application_language); | ||
| 34 | |||
| 35 | private: | ||
| 36 | void GetApplicationControlData(HLERequestContext& ctx); | ||
| 37 | void GetApplicationDesiredLanguage(HLERequestContext& ctx); | ||
| 38 | void ConvertApplicationLanguageToLanguageCode(HLERequestContext& ctx); | ||
| 39 | }; | ||
| 40 | |||
| 41 | class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> { | ||
| 42 | public: | ||
| 43 | explicit IApplicationVersionInterface(Core::System& system_); | ||
| 44 | ~IApplicationVersionInterface() override; | ||
| 45 | }; | ||
| 46 | |||
| 47 | class IContentManagementInterface final : public ServiceFramework<IContentManagementInterface> { | ||
| 48 | public: | ||
| 49 | explicit IContentManagementInterface(Core::System& system_); | ||
| 50 | ~IContentManagementInterface() override; | ||
| 51 | |||
| 52 | private: | ||
| 53 | void GetTotalSpaceSize(HLERequestContext& ctx); | ||
| 54 | void GetFreeSpaceSize(HLERequestContext& ctx); | ||
| 55 | }; | ||
| 56 | |||
| 57 | class IDocumentInterface final : public ServiceFramework<IDocumentInterface> { | ||
| 58 | public: | ||
| 59 | explicit IDocumentInterface(Core::System& system_); | ||
| 60 | ~IDocumentInterface() override; | ||
| 61 | |||
| 62 | private: | ||
| 63 | void ResolveApplicationContentPath(HLERequestContext& ctx); | ||
| 64 | void GetRunningApplicationProgramId(HLERequestContext& ctx); | ||
| 65 | }; | ||
| 66 | |||
| 67 | class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> { | ||
| 68 | public: | ||
| 69 | explicit IDownloadTaskInterface(Core::System& system_); | ||
| 70 | ~IDownloadTaskInterface() override; | ||
| 71 | }; | ||
| 72 | |||
| 73 | class IECommerceInterface final : public ServiceFramework<IECommerceInterface> { | ||
| 74 | public: | ||
| 75 | explicit IECommerceInterface(Core::System& system_); | ||
| 76 | ~IECommerceInterface() override; | ||
| 77 | }; | ||
| 78 | |||
| 79 | class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> { | ||
| 80 | public: | ||
| 81 | explicit IFactoryResetInterface(Core::System& system_); | ||
| 82 | ~IFactoryResetInterface() override; | ||
| 83 | }; | ||
| 84 | |||
| 85 | class IReadOnlyApplicationRecordInterface final | ||
| 86 | : public ServiceFramework<IReadOnlyApplicationRecordInterface> { | ||
| 87 | public: | ||
| 88 | explicit IReadOnlyApplicationRecordInterface(Core::System& system_); | ||
| 89 | ~IReadOnlyApplicationRecordInterface() override; | ||
| 90 | |||
| 91 | private: | ||
| 92 | void HasApplicationRecord(HLERequestContext& ctx); | ||
| 93 | void IsDataCorruptedResult(HLERequestContext& ctx); | ||
| 94 | }; | ||
| 95 | |||
| 96 | class IReadOnlyApplicationControlDataInterface final | ||
| 97 | : public ServiceFramework<IReadOnlyApplicationControlDataInterface> { | ||
| 98 | public: | ||
| 99 | explicit IReadOnlyApplicationControlDataInterface(Core::System& system_); | ||
| 100 | ~IReadOnlyApplicationControlDataInterface() override; | ||
| 101 | |||
| 102 | private: | ||
| 103 | void GetApplicationControlData(HLERequestContext& ctx); | ||
| 104 | }; | ||
| 105 | |||
| 106 | class NS final : public ServiceFramework<NS> { | ||
| 107 | public: | ||
| 108 | explicit NS(const char* name, Core::System& system_); | ||
| 109 | ~NS() override; | ||
| 110 | |||
| 111 | std::shared_ptr<IApplicationManagerInterface> GetApplicationManagerInterface() const; | ||
| 112 | |||
| 113 | private: | ||
| 114 | template <typename T, typename... Args> | ||
| 115 | void PushInterface(HLERequestContext& ctx) { | ||
| 116 | LOG_DEBUG(Service_NS, "called"); | ||
| 117 | |||
| 118 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 119 | rb.Push(ResultSuccess); | ||
| 120 | rb.PushIpcInterface<T>(system); | ||
| 121 | } | ||
| 122 | |||
| 123 | void PushIApplicationManagerInterface(HLERequestContext& ctx) { | ||
| 124 | LOG_DEBUG(Service_NS, "called"); | ||
| 125 | |||
| 126 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 127 | rb.Push(ResultSuccess); | ||
| 128 | rb.PushIpcInterface<IApplicationManagerInterface>(system); | ||
| 129 | } | ||
| 130 | |||
| 131 | template <typename T, typename... Args> | ||
| 132 | std::shared_ptr<T> GetInterface(Args&&... args) const { | ||
| 133 | static_assert(std::is_base_of_v<SessionRequestHandler, T>, | ||
| 134 | "Not a base of ServiceFrameworkBase"); | ||
| 135 | |||
| 136 | return std::make_shared<T>(std::forward<Args>(args)...); | ||
| 137 | } | ||
| 138 | }; | ||
| 139 | 11 | ||
| 140 | void LoopProcess(Core::System& system); | 12 | void LoopProcess(Core::System& system); |
| 141 | 13 | ||
| 142 | } // namespace NS | 14 | } // namespace Service::NS |
| 143 | } // namespace Service | ||
diff --git a/src/core/hle/service/ns/errors.h b/src/core/hle/service/ns/ns_results.h index 16d2ea6f7..16d2ea6f7 100644 --- a/src/core/hle/service/ns/errors.h +++ b/src/core/hle/service/ns/ns_results.h | |||
diff --git a/src/core/hle/service/ns/ns_types.h b/src/core/hle/service/ns/ns_types.h new file mode 100644 index 000000000..2dd664c4e --- /dev/null +++ b/src/core/hle/service/ns/ns_types.h | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/common_funcs.h" | ||
| 7 | #include "common/uuid.h" | ||
| 8 | #include "core/file_sys/romfs_factory.h" | ||
| 9 | |||
| 10 | namespace Service::NS { | ||
| 11 | |||
| 12 | enum class ApplicationRecordType : u8 { | ||
| 13 | Installing = 2, | ||
| 14 | Installed = 3, | ||
| 15 | GameCardNotInserted = 5, | ||
| 16 | Archived = 11, | ||
| 17 | GameCard = 16, | ||
| 18 | }; | ||
| 19 | |||
| 20 | enum class ApplicationControlSource : u8 { | ||
| 21 | CacheOnly = 0, | ||
| 22 | Storage = 1, | ||
| 23 | StorageOnly = 2, | ||
| 24 | }; | ||
| 25 | |||
| 26 | enum class BackgroundNetworkUpdateState : u8 { | ||
| 27 | None, | ||
| 28 | InProgress, | ||
| 29 | Ready, | ||
| 30 | }; | ||
| 31 | |||
| 32 | struct ApplicationRecord { | ||
| 33 | u64 application_id; | ||
| 34 | ApplicationRecordType type; | ||
| 35 | u8 unknown; | ||
| 36 | INSERT_PADDING_BYTES_NOINIT(0x6); | ||
| 37 | u8 unknown2; | ||
| 38 | INSERT_PADDING_BYTES_NOINIT(0x7); | ||
| 39 | }; | ||
| 40 | static_assert(sizeof(ApplicationRecord) == 0x18, "ApplicationRecord has incorrect size."); | ||
| 41 | |||
| 42 | /// ApplicationView | ||
| 43 | struct ApplicationView { | ||
| 44 | u64 application_id; ///< ApplicationId. | ||
| 45 | u32 unk; ///< Unknown. | ||
| 46 | u32 flags; ///< Flags. | ||
| 47 | std::array<u8, 0x10> unk_x10; ///< Unknown. | ||
| 48 | u32 unk_x20; ///< Unknown. | ||
| 49 | u16 unk_x24; ///< Unknown. | ||
| 50 | std::array<u8, 0x2> unk_x26; ///< Unknown. | ||
| 51 | std::array<u8, 0x8> unk_x28; ///< Unknown. | ||
| 52 | std::array<u8, 0x10> unk_x30; ///< Unknown. | ||
| 53 | u32 unk_x40; ///< Unknown. | ||
| 54 | u8 unk_x44; ///< Unknown. | ||
| 55 | std::array<u8, 0xb> unk_x45; ///< Unknown. | ||
| 56 | }; | ||
| 57 | static_assert(sizeof(ApplicationView) == 0x50, "ApplicationView has incorrect size."); | ||
| 58 | |||
| 59 | struct ApplicationRightsOnClient { | ||
| 60 | u64 application_id; | ||
| 61 | Common::UUID uid; | ||
| 62 | u8 flags; | ||
| 63 | u8 flags2; | ||
| 64 | INSERT_PADDING_BYTES_NOINIT(0x6); | ||
| 65 | }; | ||
| 66 | static_assert(sizeof(ApplicationRightsOnClient) == 0x20, | ||
| 67 | "ApplicationRightsOnClient has incorrect size."); | ||
| 68 | |||
| 69 | /// NsPromotionInfo | ||
| 70 | struct PromotionInfo { | ||
| 71 | u64 start_timestamp; ///< POSIX timestamp for the promotion start. | ||
| 72 | u64 end_timestamp; ///< POSIX timestamp for the promotion end. | ||
| 73 | s64 remaining_time; ///< Remaining time until the promotion ends, in nanoseconds | ||
| 74 | ///< ({end_timestamp - current_time} converted to nanoseconds). | ||
| 75 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 76 | u8 flags; ///< Flags. Bit0: whether the PromotionInfo is valid (including bit1). Bit1 clear: | ||
| 77 | ///< remaining_time is set. | ||
| 78 | INSERT_PADDING_BYTES_NOINIT(0x3); | ||
| 79 | }; | ||
| 80 | static_assert(sizeof(PromotionInfo) == 0x20, "PromotionInfo has incorrect size."); | ||
| 81 | |||
| 82 | /// NsApplicationViewWithPromotionInfo | ||
| 83 | struct ApplicationViewWithPromotionInfo { | ||
| 84 | ApplicationView view; ///< \ref NsApplicationView | ||
| 85 | PromotionInfo promotion; ///< \ref NsPromotionInfo | ||
| 86 | }; | ||
| 87 | static_assert(sizeof(ApplicationViewWithPromotionInfo) == 0x70, | ||
| 88 | "ApplicationViewWithPromotionInfo has incorrect size."); | ||
| 89 | |||
| 90 | struct ApplicationOccupiedSizeEntity { | ||
| 91 | FileSys::StorageId storage_id; | ||
| 92 | u64 app_size; | ||
| 93 | u64 patch_size; | ||
| 94 | u64 aoc_size; | ||
| 95 | }; | ||
| 96 | static_assert(sizeof(ApplicationOccupiedSizeEntity) == 0x20, | ||
| 97 | "ApplicationOccupiedSizeEntity has incorrect size."); | ||
| 98 | |||
| 99 | struct ApplicationOccupiedSize { | ||
| 100 | std::array<ApplicationOccupiedSizeEntity, 4> entities; | ||
| 101 | }; | ||
| 102 | static_assert(sizeof(ApplicationOccupiedSize) == 0x80, | ||
| 103 | "ApplicationOccupiedSize has incorrect size."); | ||
| 104 | |||
| 105 | struct ContentPath { | ||
| 106 | u8 file_system_proxy_type; | ||
| 107 | u64 program_id; | ||
| 108 | }; | ||
| 109 | static_assert(sizeof(ContentPath) == 0x10, "ContentPath has incorrect size."); | ||
| 110 | |||
| 111 | struct Uid { | ||
| 112 | alignas(8) Common::UUID uuid; | ||
| 113 | }; | ||
| 114 | static_assert(sizeof(Uid) == 0x10, "Uid has incorrect size."); | ||
| 115 | |||
| 116 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/pdm_qry.cpp b/src/core/hle/service/ns/pdm_qry.cpp deleted file mode 100644 index ce0ee30e0..000000000 --- a/src/core/hle/service/ns/pdm_qry.cpp +++ /dev/null | |||
| @@ -1,67 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include <memory> | ||
| 5 | |||
| 6 | #include "common/logging/log.h" | ||
| 7 | #include "common/uuid.h" | ||
| 8 | #include "core/hle/service/ipc_helpers.h" | ||
| 9 | #include "core/hle/service/ns/pdm_qry.h" | ||
| 10 | #include "core/hle/service/service.h" | ||
| 11 | |||
| 12 | namespace Service::NS { | ||
| 13 | |||
| 14 | PDM_QRY::PDM_QRY(Core::System& system_) : ServiceFramework{system_, "pdm:qry"} { | ||
| 15 | // clang-format off | ||
| 16 | static const FunctionInfo functions[] = { | ||
| 17 | {0, nullptr, "QueryAppletEvent"}, | ||
| 18 | {1, nullptr, "QueryPlayStatistics"}, | ||
| 19 | {2, nullptr, "QueryPlayStatisticsByUserAccountId"}, | ||
| 20 | {3, nullptr, "QueryPlayStatisticsByNetworkServiceAccountId"}, | ||
| 21 | {4, nullptr, "QueryPlayStatisticsByApplicationId"}, | ||
| 22 | {5, &PDM_QRY::QueryPlayStatisticsByApplicationIdAndUserAccountId, "QueryPlayStatisticsByApplicationIdAndUserAccountId"}, | ||
| 23 | {6, nullptr, "QueryPlayStatisticsByApplicationIdAndNetworkServiceAccountId"}, | ||
| 24 | {7, nullptr, "QueryLastPlayTimeV0"}, | ||
| 25 | {8, nullptr, "QueryPlayEvent"}, | ||
| 26 | {9, nullptr, "GetAvailablePlayEventRange"}, | ||
| 27 | {10, nullptr, "QueryAccountEvent"}, | ||
| 28 | {11, nullptr, "QueryAccountPlayEvent"}, | ||
| 29 | {12, nullptr, "GetAvailableAccountPlayEventRange"}, | ||
| 30 | {13, nullptr, "QueryApplicationPlayStatisticsForSystemV0"}, | ||
| 31 | {14, nullptr, "QueryRecentlyPlayedApplication"}, | ||
| 32 | {15, nullptr, "GetRecentlyPlayedApplicationUpdateEvent"}, | ||
| 33 | {16, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystemV0"}, | ||
| 34 | {17, nullptr, "QueryLastPlayTime"}, | ||
| 35 | {18, nullptr, "QueryApplicationPlayStatisticsForSystem"}, | ||
| 36 | {19, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystem"}, | ||
| 37 | }; | ||
| 38 | // clang-format on | ||
| 39 | |||
| 40 | RegisterHandlers(functions); | ||
| 41 | } | ||
| 42 | |||
| 43 | PDM_QRY::~PDM_QRY() = default; | ||
| 44 | |||
| 45 | void PDM_QRY::QueryPlayStatisticsByApplicationIdAndUserAccountId(HLERequestContext& ctx) { | ||
| 46 | IPC::RequestParser rp{ctx}; | ||
| 47 | const auto unknown = rp.Pop<bool>(); | ||
| 48 | rp.Pop<u8>(); // Padding | ||
| 49 | const auto application_id = rp.Pop<u64>(); | ||
| 50 | const auto user_account_uid = rp.PopRaw<Common::UUID>(); | ||
| 51 | |||
| 52 | // TODO(German77): Read statistics of the game | ||
| 53 | PlayStatistics statistics{ | ||
| 54 | .application_id = application_id, | ||
| 55 | .total_launches = 1, | ||
| 56 | }; | ||
| 57 | |||
| 58 | LOG_WARNING(Service_NS, | ||
| 59 | "(STUBBED) called. unknown={}. application_id=0x{:016X}, user_account_uid=0x{}", | ||
| 60 | unknown, application_id, user_account_uid.RawString()); | ||
| 61 | |||
| 62 | IPC::ResponseBuilder rb{ctx, 12}; | ||
| 63 | rb.Push(ResultSuccess); | ||
| 64 | rb.PushRaw(statistics); | ||
| 65 | } | ||
| 66 | |||
| 67 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/iplatform_service_manager.cpp b/src/core/hle/service/ns/platform_service_manager.cpp index 46268be95..23cf05005 100644 --- a/src/core/hle/service/ns/iplatform_service_manager.cpp +++ b/src/core/hle/service/ns/platform_service_manager.cpp | |||
| @@ -18,9 +18,9 @@ | |||
| 18 | #include "core/hle/kernel/k_shared_memory.h" | 18 | #include "core/hle/kernel/k_shared_memory.h" |
| 19 | #include "core/hle/kernel/kernel.h" | 19 | #include "core/hle/kernel/kernel.h" |
| 20 | #include "core/hle/kernel/physical_memory.h" | 20 | #include "core/hle/kernel/physical_memory.h" |
| 21 | #include "core/hle/service/cmif_serialization.h" | ||
| 21 | #include "core/hle/service/filesystem/filesystem.h" | 22 | #include "core/hle/service/filesystem/filesystem.h" |
| 22 | #include "core/hle/service/ipc_helpers.h" | 23 | #include "core/hle/service/ns/platform_service_manager.h" |
| 23 | #include "core/hle/service/ns/iplatform_service_manager.h" | ||
| 24 | 24 | ||
| 25 | namespace Service::NS { | 25 | namespace Service::NS { |
| 26 | 26 | ||
| @@ -37,11 +37,6 @@ constexpr u32 EXPECTED_MAGIC{0x36f81a1e}; // What we expect the encrypted bfttf | |||
| 37 | constexpr u64 SHARED_FONT_MEM_SIZE{0x1100000}; | 37 | constexpr u64 SHARED_FONT_MEM_SIZE{0x1100000}; |
| 38 | constexpr FontRegion EMPTY_REGION{0, 0}; | 38 | constexpr FontRegion EMPTY_REGION{0, 0}; |
| 39 | 39 | ||
| 40 | enum class LoadState : u32 { | ||
| 41 | Loading = 0, | ||
| 42 | Done = 1, | ||
| 43 | }; | ||
| 44 | |||
| 45 | static void DecryptSharedFont(const std::vector<u32>& input, Kernel::PhysicalMemory& output, | 40 | static void DecryptSharedFont(const std::vector<u32>& input, Kernel::PhysicalMemory& output, |
| 46 | std::size_t& offset) { | 41 | std::size_t& offset) { |
| 47 | ASSERT_MSG(offset + (input.size() * sizeof(u32)) < SHARED_FONT_MEM_SIZE, | 42 | ASSERT_MSG(offset + (input.size() * sizeof(u32)) < SHARED_FONT_MEM_SIZE, |
| @@ -138,13 +133,13 @@ IPlatformServiceManager::IPlatformServiceManager(Core::System& system_, const ch | |||
| 138 | : ServiceFramework{system_, service_name_}, impl{std::make_unique<Impl>()} { | 133 | : ServiceFramework{system_, service_name_}, impl{std::make_unique<Impl>()} { |
| 139 | // clang-format off | 134 | // clang-format off |
| 140 | static const FunctionInfo functions[] = { | 135 | static const FunctionInfo functions[] = { |
| 141 | {0, &IPlatformServiceManager::RequestLoad, "RequestLoad"}, | 136 | {0, D<&IPlatformServiceManager::RequestLoad>, "RequestLoad"}, |
| 142 | {1, &IPlatformServiceManager::GetLoadState, "GetLoadState"}, | 137 | {1, D<&IPlatformServiceManager::GetLoadState>, "GetLoadState"}, |
| 143 | {2, &IPlatformServiceManager::GetSize, "GetSize"}, | 138 | {2, D<&IPlatformServiceManager::GetSize>, "GetSize"}, |
| 144 | {3, &IPlatformServiceManager::GetSharedMemoryAddressOffset, "GetSharedMemoryAddressOffset"}, | 139 | {3, D<&IPlatformServiceManager::GetSharedMemoryAddressOffset>, "GetSharedMemoryAddressOffset"}, |
| 145 | {4, &IPlatformServiceManager::GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"}, | 140 | {4, D<&IPlatformServiceManager::GetSharedMemoryNativeHandle>, "GetSharedMemoryNativeHandle"}, |
| 146 | {5, &IPlatformServiceManager::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriority"}, | 141 | {5, D<&IPlatformServiceManager::GetSharedFontInOrderOfPriority>, "GetSharedFontInOrderOfPriority"}, |
| 147 | {6, &IPlatformServiceManager::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriorityForSystem"}, | 142 | {6, D<&IPlatformServiceManager::GetSharedFontInOrderOfPriority>, "GetSharedFontInOrderOfPriorityForSystem"}, |
| 148 | {100, nullptr, "RequestApplicationFunctionAuthorization"}, | 143 | {100, nullptr, "RequestApplicationFunctionAuthorization"}, |
| 149 | {101, nullptr, "RequestApplicationFunctionAuthorizationByProcessId"}, | 144 | {101, nullptr, "RequestApplicationFunctionAuthorizationByProcessId"}, |
| 150 | {102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"}, | 145 | {102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"}, |
| @@ -208,47 +203,33 @@ IPlatformServiceManager::IPlatformServiceManager(Core::System& system_, const ch | |||
| 208 | 203 | ||
| 209 | IPlatformServiceManager::~IPlatformServiceManager() = default; | 204 | IPlatformServiceManager::~IPlatformServiceManager() = default; |
| 210 | 205 | ||
| 211 | void IPlatformServiceManager::RequestLoad(HLERequestContext& ctx) { | 206 | Result IPlatformServiceManager::RequestLoad(SharedFontType type) { |
| 212 | IPC::RequestParser rp{ctx}; | ||
| 213 | const u32 shared_font_type{rp.Pop<u32>()}; | ||
| 214 | // Games don't call this so all fonts should be loaded | 207 | // Games don't call this so all fonts should be loaded |
| 215 | LOG_DEBUG(Service_NS, "called, shared_font_type={}", shared_font_type); | 208 | LOG_DEBUG(Service_NS, "called, shared_font_type={}", type); |
| 216 | 209 | R_SUCCEED(); | |
| 217 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 218 | rb.Push(ResultSuccess); | ||
| 219 | } | 210 | } |
| 220 | 211 | ||
| 221 | void IPlatformServiceManager::GetLoadState(HLERequestContext& ctx) { | 212 | Result IPlatformServiceManager::GetLoadState(Out<LoadState> out_load_state, SharedFontType type) { |
| 222 | IPC::RequestParser rp{ctx}; | 213 | LOG_DEBUG(Service_NS, "called, shared_font_type={}", type); |
| 223 | const u32 font_id{rp.Pop<u32>()}; | 214 | *out_load_state = LoadState::Loaded; |
| 224 | LOG_DEBUG(Service_NS, "called, font_id={}", font_id); | 215 | R_SUCCEED(); |
| 225 | |||
| 226 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 227 | rb.Push(ResultSuccess); | ||
| 228 | rb.Push<u32>(static_cast<u32>(LoadState::Done)); | ||
| 229 | } | 216 | } |
| 230 | 217 | ||
| 231 | void IPlatformServiceManager::GetSize(HLERequestContext& ctx) { | 218 | Result IPlatformServiceManager::GetSize(Out<u32> out_size, SharedFontType type) { |
| 232 | IPC::RequestParser rp{ctx}; | 219 | LOG_DEBUG(Service_NS, "called, shared_font_type={}", type); |
| 233 | const u32 font_id{rp.Pop<u32>()}; | 220 | *out_size = impl->GetSharedFontRegion(static_cast<size_t>(type)).size; |
| 234 | LOG_DEBUG(Service_NS, "called, font_id={}", font_id); | 221 | R_SUCCEED(); |
| 235 | |||
| 236 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 237 | rb.Push(ResultSuccess); | ||
| 238 | rb.Push<u32>(impl->GetSharedFontRegion(font_id).size); | ||
| 239 | } | 222 | } |
| 240 | 223 | ||
| 241 | void IPlatformServiceManager::GetSharedMemoryAddressOffset(HLERequestContext& ctx) { | 224 | Result IPlatformServiceManager::GetSharedMemoryAddressOffset(Out<u32> out_shared_memory_offset, |
| 242 | IPC::RequestParser rp{ctx}; | 225 | SharedFontType type) { |
| 243 | const u32 font_id{rp.Pop<u32>()}; | 226 | LOG_DEBUG(Service_NS, "called, shared_font_type={}", type); |
| 244 | LOG_DEBUG(Service_NS, "called, font_id={}", font_id); | 227 | *out_shared_memory_offset = impl->GetSharedFontRegion(static_cast<size_t>(type)).offset; |
| 245 | 228 | R_SUCCEED(); | |
| 246 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 247 | rb.Push(ResultSuccess); | ||
| 248 | rb.Push<u32>(impl->GetSharedFontRegion(font_id).offset); | ||
| 249 | } | 229 | } |
| 250 | 230 | ||
| 251 | void IPlatformServiceManager::GetSharedMemoryNativeHandle(HLERequestContext& ctx) { | 231 | Result IPlatformServiceManager::GetSharedMemoryNativeHandle( |
| 232 | OutCopyHandle<Kernel::KSharedMemory> out_shared_memory_native_handle) { | ||
| 252 | // Map backing memory for the font data | 233 | // Map backing memory for the font data |
| 253 | LOG_DEBUG(Service_NS, "called"); | 234 | LOG_DEBUG(Service_NS, "called"); |
| 254 | 235 | ||
| @@ -256,50 +237,37 @@ void IPlatformServiceManager::GetSharedMemoryNativeHandle(HLERequestContext& ctx | |||
| 256 | std::memcpy(kernel.GetFontSharedMem().GetPointer(), impl->shared_font->data(), | 237 | std::memcpy(kernel.GetFontSharedMem().GetPointer(), impl->shared_font->data(), |
| 257 | impl->shared_font->size()); | 238 | impl->shared_font->size()); |
| 258 | 239 | ||
| 259 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 240 | // FIXME: this shouldn't belong to the kernel |
| 260 | rb.Push(ResultSuccess); | 241 | *out_shared_memory_native_handle = &kernel.GetFontSharedMem(); |
| 261 | rb.PushCopyObjects(&kernel.GetFontSharedMem()); | 242 | R_SUCCEED(); |
| 262 | } | 243 | } |
| 263 | 244 | ||
| 264 | void IPlatformServiceManager::GetSharedFontInOrderOfPriority(HLERequestContext& ctx) { | 245 | Result IPlatformServiceManager::GetSharedFontInOrderOfPriority( |
| 246 | OutArray<u32, BufferAttr_HipcMapAlias> out_font_codes, | ||
| 247 | OutArray<u32, BufferAttr_HipcMapAlias> out_font_offsets, | ||
| 248 | OutArray<u32, BufferAttr_HipcMapAlias> out_font_sizes, Out<bool> out_fonts_are_loaded, | ||
| 249 | Out<u32> out_font_count, Set::LanguageCode language_code) { | ||
| 250 | LOG_DEBUG(Service_NS, "called, language_code={:#x}", language_code); | ||
| 251 | |||
| 265 | // The maximum number of elements that can be returned is 6. Regardless of the available fonts | 252 | // The maximum number of elements that can be returned is 6. Regardless of the available fonts |
| 266 | // or buffer size. | 253 | // or buffer size. |
| 267 | constexpr std::size_t MaxElementCount = 6; | 254 | constexpr size_t MaxElementCount = 6; |
| 268 | IPC::RequestParser rp{ctx}; | ||
| 269 | const u64 language_code{rp.Pop<u64>()}; // TODO(ogniK): Find out what this is used for | ||
| 270 | const std::size_t font_codes_count = | ||
| 271 | std::min(MaxElementCount, ctx.GetWriteBufferNumElements<u32>(0)); | ||
| 272 | const std::size_t font_offsets_count = | ||
| 273 | std::min(MaxElementCount, ctx.GetWriteBufferNumElements<u32>(1)); | ||
| 274 | const std::size_t font_sizes_count = | ||
| 275 | std::min(MaxElementCount, ctx.GetWriteBufferNumElements<u32>(2)); | ||
| 276 | LOG_DEBUG(Service_NS, "called, language_code={:X}", language_code); | ||
| 277 | |||
| 278 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 279 | std::vector<u32> font_codes; | ||
| 280 | std::vector<u32> font_offsets; | ||
| 281 | std::vector<u32> font_sizes; | ||
| 282 | 255 | ||
| 283 | // TODO(ogniK): Have actual priority order | 256 | // TODO(ogniK): Have actual priority order |
| 284 | for (std::size_t i = 0; i < impl->shared_font_regions.size(); i++) { | 257 | const auto max_size = std::min({MaxElementCount, out_font_codes.size(), out_font_offsets.size(), |
| 285 | font_codes.push_back(static_cast<u32>(i)); | 258 | out_font_sizes.size(), impl->shared_font_regions.size()}); |
| 286 | auto region = impl->GetSharedFontRegion(i); | ||
| 287 | font_offsets.push_back(region.offset); | ||
| 288 | font_sizes.push_back(region.size); | ||
| 289 | } | ||
| 290 | 259 | ||
| 291 | // Resize buffers if game requests smaller size output | 260 | for (size_t i = 0; i < max_size; i++) { |
| 292 | font_codes.resize(std::min(font_codes.size(), font_codes_count)); | 261 | auto region = impl->GetSharedFontRegion(i); |
| 293 | font_offsets.resize(std::min(font_offsets.size(), font_offsets_count)); | ||
| 294 | font_sizes.resize(std::min(font_sizes.size(), font_sizes_count)); | ||
| 295 | 262 | ||
| 296 | ctx.WriteBuffer(font_codes, 0); | 263 | out_font_codes[i] = static_cast<u32>(i); |
| 297 | ctx.WriteBuffer(font_offsets, 1); | 264 | out_font_offsets[i] = region.offset; |
| 298 | ctx.WriteBuffer(font_sizes, 2); | 265 | out_font_sizes[i] = region.size; |
| 266 | } | ||
| 299 | 267 | ||
| 300 | rb.Push(ResultSuccess); | 268 | *out_fonts_are_loaded = true; |
| 301 | rb.Push<u8>(static_cast<u8>(LoadState::Done)); // Fonts Loaded | 269 | *out_font_count = static_cast<u32>(max_size); |
| 302 | rb.Push<u32>(static_cast<u32>(font_codes.size())); | 270 | R_SUCCEED(); |
| 303 | } | 271 | } |
| 304 | 272 | ||
| 305 | } // namespace Service::NS | 273 | } // namespace Service::NS |
diff --git a/src/core/hle/service/ns/iplatform_service_manager.h b/src/core/hle/service/ns/platform_service_manager.h index 03071e02b..b82c385a6 100644 --- a/src/core/hle/service/ns/iplatform_service_manager.h +++ b/src/core/hle/service/ns/platform_service_manager.h | |||
| @@ -5,7 +5,9 @@ | |||
| 5 | 5 | ||
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | #include "core/hle/service/cmif_types.h" | ||
| 8 | #include "core/hle/service/service.h" | 9 | #include "core/hle/service/service.h" |
| 10 | #include "core/hle/service/set/settings_types.h" | ||
| 9 | 11 | ||
| 10 | namespace Service { | 12 | namespace Service { |
| 11 | 13 | ||
| @@ -23,6 +25,20 @@ enum class FontArchives : u64 { | |||
| 23 | ChineseSimple = 0x0100000000000814, | 25 | ChineseSimple = 0x0100000000000814, |
| 24 | }; | 26 | }; |
| 25 | 27 | ||
| 28 | enum class SharedFontType : u32 { | ||
| 29 | JapanUSEuropeStandard = 0, | ||
| 30 | ChineseSimplified = 1, | ||
| 31 | ExtendedChineseSimplified = 2, | ||
| 32 | ChineseTraditional = 3, | ||
| 33 | KoreanHangul = 4, | ||
| 34 | NintendoExtended = 5, | ||
| 35 | }; | ||
| 36 | |||
| 37 | enum class LoadState : u32 { | ||
| 38 | Loading = 0, | ||
| 39 | Loaded = 1, | ||
| 40 | }; | ||
| 41 | |||
| 26 | constexpr std::array<std::pair<FontArchives, const char*>, 7> SHARED_FONTS{ | 42 | constexpr std::array<std::pair<FontArchives, const char*>, 7> SHARED_FONTS{ |
| 27 | std::make_pair(FontArchives::Standard, "nintendo_udsg-r_std_003.bfttf"), | 43 | std::make_pair(FontArchives::Standard, "nintendo_udsg-r_std_003.bfttf"), |
| 28 | std::make_pair(FontArchives::ChineseSimple, "nintendo_udsg-r_org_zh-cn_003.bfttf"), | 44 | std::make_pair(FontArchives::ChineseSimple, "nintendo_udsg-r_org_zh-cn_003.bfttf"), |
| @@ -42,12 +58,17 @@ public: | |||
| 42 | ~IPlatformServiceManager() override; | 58 | ~IPlatformServiceManager() override; |
| 43 | 59 | ||
| 44 | private: | 60 | private: |
| 45 | void RequestLoad(HLERequestContext& ctx); | 61 | Result RequestLoad(SharedFontType type); |
| 46 | void GetLoadState(HLERequestContext& ctx); | 62 | Result GetLoadState(Out<LoadState> out_load_state, SharedFontType type); |
| 47 | void GetSize(HLERequestContext& ctx); | 63 | Result GetSize(Out<u32> out_size, SharedFontType type); |
| 48 | void GetSharedMemoryAddressOffset(HLERequestContext& ctx); | 64 | Result GetSharedMemoryAddressOffset(Out<u32> out_shared_memory_offset, SharedFontType type); |
| 49 | void GetSharedMemoryNativeHandle(HLERequestContext& ctx); | 65 | Result GetSharedMemoryNativeHandle( |
| 50 | void GetSharedFontInOrderOfPriority(HLERequestContext& ctx); | 66 | OutCopyHandle<Kernel::KSharedMemory> out_shared_memory_native_handle); |
| 67 | Result GetSharedFontInOrderOfPriority(OutArray<u32, BufferAttr_HipcMapAlias> out_font_codes, | ||
| 68 | OutArray<u32, BufferAttr_HipcMapAlias> out_font_offsets, | ||
| 69 | OutArray<u32, BufferAttr_HipcMapAlias> out_font_sizes, | ||
| 70 | Out<bool> out_fonts_are_loaded, Out<u32> out_font_count, | ||
| 71 | Set::LanguageCode language_code); | ||
| 51 | 72 | ||
| 52 | struct Impl; | 73 | struct Impl; |
| 53 | std::unique_ptr<Impl> impl; | 74 | std::unique_ptr<Impl> impl; |
diff --git a/src/core/hle/service/ns/query_service.cpp b/src/core/hle/service/ns/query_service.cpp new file mode 100644 index 000000000..138400541 --- /dev/null +++ b/src/core/hle/service/ns/query_service.cpp | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/logging/log.h" | ||
| 5 | #include "common/uuid.h" | ||
| 6 | #include "core/hle/service/cmif_serialization.h" | ||
| 7 | #include "core/hle/service/ns/query_service.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | |||
| 10 | namespace Service::NS { | ||
| 11 | |||
| 12 | IQueryService::IQueryService(Core::System& system_) : ServiceFramework{system_, "pdm:qry"} { | ||
| 13 | // clang-format off | ||
| 14 | static const FunctionInfo functions[] = { | ||
| 15 | {0, nullptr, "QueryAppletEvent"}, | ||
| 16 | {1, nullptr, "QueryPlayStatistics"}, | ||
| 17 | {2, nullptr, "QueryPlayStatisticsByUserAccountId"}, | ||
| 18 | {3, nullptr, "QueryPlayStatisticsByNetworkServiceAccountId"}, | ||
| 19 | {4, nullptr, "QueryPlayStatisticsByApplicationId"}, | ||
| 20 | {5, D<&IQueryService::QueryPlayStatisticsByApplicationIdAndUserAccountId>, "QueryPlayStatisticsByApplicationIdAndUserAccountId"}, | ||
| 21 | {6, nullptr, "QueryPlayStatisticsByApplicationIdAndNetworkServiceAccountId"}, | ||
| 22 | {7, nullptr, "QueryLastPlayTimeV0"}, | ||
| 23 | {8, nullptr, "QueryPlayEvent"}, | ||
| 24 | {9, nullptr, "GetAvailablePlayEventRange"}, | ||
| 25 | {10, nullptr, "QueryAccountEvent"}, | ||
| 26 | {11, nullptr, "QueryAccountPlayEvent"}, | ||
| 27 | {12, nullptr, "GetAvailableAccountPlayEventRange"}, | ||
| 28 | {13, nullptr, "QueryApplicationPlayStatisticsForSystemV0"}, | ||
| 29 | {14, nullptr, "QueryRecentlyPlayedApplication"}, | ||
| 30 | {15, nullptr, "GetRecentlyPlayedApplicationUpdateEvent"}, | ||
| 31 | {16, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystemV0"}, | ||
| 32 | {17, nullptr, "QueryLastPlayTime"}, | ||
| 33 | {18, nullptr, "QueryApplicationPlayStatisticsForSystem"}, | ||
| 34 | {19, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystem"}, | ||
| 35 | }; | ||
| 36 | // clang-format on | ||
| 37 | |||
| 38 | RegisterHandlers(functions); | ||
| 39 | } | ||
| 40 | |||
| 41 | IQueryService::~IQueryService() = default; | ||
| 42 | |||
| 43 | Result IQueryService::QueryPlayStatisticsByApplicationIdAndUserAccountId( | ||
| 44 | Out<PlayStatistics> out_play_statistics, bool unknown, u64 application_id, Uid account_id) { | ||
| 45 | // TODO(German77): Read statistics of the game | ||
| 46 | *out_play_statistics = { | ||
| 47 | .application_id = application_id, | ||
| 48 | .total_launches = 1, | ||
| 49 | }; | ||
| 50 | |||
| 51 | LOG_WARNING(Service_NS, "(STUBBED) called. unknown={}. application_id={:016X}, account_id={}", | ||
| 52 | unknown, application_id, account_id.uuid.FormattedString()); | ||
| 53 | R_SUCCEED(); | ||
| 54 | } | ||
| 55 | |||
| 56 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/pdm_qry.h b/src/core/hle/service/ns/query_service.h index c98e01660..c4c82b752 100644 --- a/src/core/hle/service/ns/pdm_qry.h +++ b/src/core/hle/service/ns/query_service.h | |||
| @@ -3,6 +3,9 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "common/uuid.h" | ||
| 7 | #include "core/hle/service/cmif_types.h" | ||
| 8 | #include "core/hle/service/ns/ns_types.h" | ||
| 6 | #include "core/hle/service/service.h" | 9 | #include "core/hle/service/service.h" |
| 7 | 10 | ||
| 8 | namespace Service::NS { | 11 | namespace Service::NS { |
| @@ -20,13 +23,14 @@ struct PlayStatistics { | |||
| 20 | }; | 23 | }; |
| 21 | static_assert(sizeof(PlayStatistics) == 0x28, "PlayStatistics is an invalid size"); | 24 | static_assert(sizeof(PlayStatistics) == 0x28, "PlayStatistics is an invalid size"); |
| 22 | 25 | ||
| 23 | class PDM_QRY final : public ServiceFramework<PDM_QRY> { | 26 | class IQueryService final : public ServiceFramework<IQueryService> { |
| 24 | public: | 27 | public: |
| 25 | explicit PDM_QRY(Core::System& system_); | 28 | explicit IQueryService(Core::System& system_); |
| 26 | ~PDM_QRY() override; | 29 | ~IQueryService() override; |
| 27 | 30 | ||
| 28 | private: | 31 | private: |
| 29 | void QueryPlayStatisticsByApplicationIdAndUserAccountId(HLERequestContext& ctx); | 32 | Result QueryPlayStatisticsByApplicationIdAndUserAccountId( |
| 33 | Out<PlayStatistics> out_play_statistics, bool unknown, u64 application_id, Uid account_id); | ||
| 30 | }; | 34 | }; |
| 31 | 35 | ||
| 32 | } // namespace Service::NS | 36 | } // namespace Service::NS |
diff --git a/src/core/hle/service/ns/read_only_application_control_data_interface.cpp b/src/core/hle/service/ns/read_only_application_control_data_interface.cpp new file mode 100644 index 000000000..9b2ca94a4 --- /dev/null +++ b/src/core/hle/service/ns/read_only_application_control_data_interface.cpp | |||
| @@ -0,0 +1,122 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/settings.h" | ||
| 5 | #include "core/file_sys/control_metadata.h" | ||
| 6 | #include "core/file_sys/patch_manager.h" | ||
| 7 | #include "core/file_sys/vfs/vfs.h" | ||
| 8 | #include "core/hle/service/cmif_serialization.h" | ||
| 9 | #include "core/hle/service/ns/language.h" | ||
| 10 | #include "core/hle/service/ns/ns_results.h" | ||
| 11 | #include "core/hle/service/ns/read_only_application_control_data_interface.h" | ||
| 12 | #include "core/hle/service/set/settings_server.h" | ||
| 13 | |||
| 14 | namespace Service::NS { | ||
| 15 | |||
| 16 | IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterface( | ||
| 17 | Core::System& system_) | ||
| 18 | : ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} { | ||
| 19 | // clang-format off | ||
| 20 | static const FunctionInfo functions[] = { | ||
| 21 | {0, D<&IReadOnlyApplicationControlDataInterface::GetApplicationControlData>, "GetApplicationControlData"}, | ||
| 22 | {1, D<&IReadOnlyApplicationControlDataInterface::GetApplicationDesiredLanguage>, "GetApplicationDesiredLanguage"}, | ||
| 23 | {2, D<&IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLanguageCode>, "ConvertApplicationLanguageToLanguageCode"}, | ||
| 24 | {3, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, | ||
| 25 | {4, nullptr, "SelectApplicationDesiredLanguage"}, | ||
| 26 | }; | ||
| 27 | // clang-format on | ||
| 28 | |||
| 29 | RegisterHandlers(functions); | ||
| 30 | } | ||
| 31 | |||
| 32 | IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default; | ||
| 33 | |||
| 34 | Result IReadOnlyApplicationControlDataInterface::GetApplicationControlData( | ||
| 35 | OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u32> out_actual_size, | ||
| 36 | ApplicationControlSource application_control_source, u64 application_id) { | ||
| 37 | LOG_INFO(Service_NS, "called with control_source={}, application_id={:016X}", | ||
| 38 | application_control_source, application_id); | ||
| 39 | |||
| 40 | const FileSys::PatchManager pm{application_id, system.GetFileSystemController(), | ||
| 41 | system.GetContentProvider()}; | ||
| 42 | const auto control = pm.GetControlMetadata(); | ||
| 43 | const auto size = out_buffer.size(); | ||
| 44 | |||
| 45 | const auto icon_size = control.second ? control.second->GetSize() : 0; | ||
| 46 | const auto total_size = sizeof(FileSys::RawNACP) + icon_size; | ||
| 47 | |||
| 48 | if (size < total_size) { | ||
| 49 | LOG_ERROR(Service_NS, "output buffer is too small! (actual={:016X}, expected_min=0x4000)", | ||
| 50 | size); | ||
| 51 | R_THROW(ResultUnknown); | ||
| 52 | } | ||
| 53 | |||
| 54 | if (control.first != nullptr) { | ||
| 55 | const auto bytes = control.first->GetRawBytes(); | ||
| 56 | std::memcpy(out_buffer.data(), bytes.data(), bytes.size()); | ||
| 57 | } else { | ||
| 58 | LOG_WARNING(Service_NS, "missing NACP data for application_id={:016X}, defaulting to zero", | ||
| 59 | application_id); | ||
| 60 | std::memset(out_buffer.data(), 0, sizeof(FileSys::RawNACP)); | ||
| 61 | } | ||
| 62 | |||
| 63 | if (control.second != nullptr) { | ||
| 64 | control.second->Read(out_buffer.data() + sizeof(FileSys::RawNACP), icon_size); | ||
| 65 | } else { | ||
| 66 | LOG_WARNING(Service_NS, "missing icon data for application_id={:016X}", application_id); | ||
| 67 | } | ||
| 68 | |||
| 69 | *out_actual_size = static_cast<u32>(total_size); | ||
| 70 | R_SUCCEED(); | ||
| 71 | } | ||
| 72 | |||
| 73 | Result IReadOnlyApplicationControlDataInterface::GetApplicationDesiredLanguage( | ||
| 74 | Out<ApplicationLanguage> out_desired_language, u32 supported_languages) { | ||
| 75 | LOG_INFO(Service_NS, "called with supported_languages={:08X}", supported_languages); | ||
| 76 | |||
| 77 | // Get language code from settings | ||
| 78 | const auto language_code = | ||
| 79 | Set::GetLanguageCodeFromIndex(static_cast<s32>(Settings::values.language_index.GetValue())); | ||
| 80 | |||
| 81 | // Convert to application language, get priority list | ||
| 82 | const auto application_language = ConvertToApplicationLanguage(language_code); | ||
| 83 | if (application_language == std::nullopt) { | ||
| 84 | LOG_ERROR(Service_NS, "Could not convert application language! language_code={}", | ||
| 85 | language_code); | ||
| 86 | R_THROW(Service::NS::ResultApplicationLanguageNotFound); | ||
| 87 | } | ||
| 88 | const auto priority_list = GetApplicationLanguagePriorityList(*application_language); | ||
| 89 | if (!priority_list) { | ||
| 90 | LOG_ERROR(Service_NS, | ||
| 91 | "Could not find application language priorities! application_language={}", | ||
| 92 | *application_language); | ||
| 93 | R_THROW(Service::NS::ResultApplicationLanguageNotFound); | ||
| 94 | } | ||
| 95 | |||
| 96 | // Try to find a valid language. | ||
| 97 | for (const auto lang : *priority_list) { | ||
| 98 | const auto supported_flag = GetSupportedLanguageFlag(lang); | ||
| 99 | if (supported_languages == 0 || (supported_languages & supported_flag) == supported_flag) { | ||
| 100 | *out_desired_language = lang; | ||
| 101 | R_SUCCEED(); | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | LOG_ERROR(Service_NS, "Could not find a valid language! supported_languages={:08X}", | ||
| 106 | supported_languages); | ||
| 107 | R_THROW(Service::NS::ResultApplicationLanguageNotFound); | ||
| 108 | } | ||
| 109 | |||
| 110 | Result IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLanguageCode( | ||
| 111 | Out<u64> out_language_code, ApplicationLanguage application_language) { | ||
| 112 | const auto language_code = ConvertToLanguageCode(application_language); | ||
| 113 | if (language_code == std::nullopt) { | ||
| 114 | LOG_ERROR(Service_NS, "Language not found! application_language={}", application_language); | ||
| 115 | R_THROW(Service::NS::ResultApplicationLanguageNotFound); | ||
| 116 | } | ||
| 117 | |||
| 118 | *out_language_code = static_cast<u64>(*language_code); | ||
| 119 | R_SUCCEED(); | ||
| 120 | } | ||
| 121 | |||
| 122 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/read_only_application_control_data_interface.h b/src/core/hle/service/ns/read_only_application_control_data_interface.h new file mode 100644 index 000000000..ac099435a --- /dev/null +++ b/src/core/hle/service/ns/read_only_application_control_data_interface.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/ns/language.h" | ||
| 8 | #include "core/hle/service/ns/ns_types.h" | ||
| 9 | #include "core/hle/service/service.h" | ||
| 10 | |||
| 11 | namespace Service::NS { | ||
| 12 | |||
| 13 | class IReadOnlyApplicationControlDataInterface final | ||
| 14 | : public ServiceFramework<IReadOnlyApplicationControlDataInterface> { | ||
| 15 | public: | ||
| 16 | explicit IReadOnlyApplicationControlDataInterface(Core::System& system_); | ||
| 17 | ~IReadOnlyApplicationControlDataInterface() override; | ||
| 18 | |||
| 19 | public: | ||
| 20 | Result GetApplicationControlData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer, | ||
| 21 | Out<u32> out_actual_size, | ||
| 22 | ApplicationControlSource application_control_source, | ||
| 23 | u64 application_id); | ||
| 24 | Result GetApplicationDesiredLanguage(Out<ApplicationLanguage> out_desired_language, | ||
| 25 | u32 supported_languages); | ||
| 26 | Result ConvertApplicationLanguageToLanguageCode(Out<u64> out_language_code, | ||
| 27 | ApplicationLanguage application_language); | ||
| 28 | }; | ||
| 29 | |||
| 30 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/read_only_application_record_interface.cpp b/src/core/hle/service/ns/read_only_application_record_interface.cpp new file mode 100644 index 000000000..816a1e1dc --- /dev/null +++ b/src/core/hle/service/ns/read_only_application_record_interface.cpp | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/cmif_serialization.h" | ||
| 5 | #include "core/hle/service/ns/read_only_application_record_interface.h" | ||
| 6 | |||
| 7 | namespace Service::NS { | ||
| 8 | |||
| 9 | IReadOnlyApplicationRecordInterface::IReadOnlyApplicationRecordInterface(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "IReadOnlyApplicationRecordInterface"} { | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, D<&IReadOnlyApplicationRecordInterface::HasApplicationRecord>, "HasApplicationRecord"}, | ||
| 13 | {1, nullptr, "NotifyApplicationFailure"}, | ||
| 14 | {2, D<&IReadOnlyApplicationRecordInterface::IsDataCorruptedResult>, | ||
| 15 | "IsDataCorruptedResult"}, | ||
| 16 | }; | ||
| 17 | // clang-format on | ||
| 18 | |||
| 19 | RegisterHandlers(functions); | ||
| 20 | } | ||
| 21 | |||
| 22 | IReadOnlyApplicationRecordInterface::~IReadOnlyApplicationRecordInterface() = default; | ||
| 23 | |||
| 24 | Result IReadOnlyApplicationRecordInterface::HasApplicationRecord( | ||
| 25 | Out<bool> out_has_application_record, u64 program_id) { | ||
| 26 | LOG_WARNING(Service_NS, "(STUBBED) called, program_id={:016X}", program_id); | ||
| 27 | *out_has_application_record = true; | ||
| 28 | R_SUCCEED(); | ||
| 29 | } | ||
| 30 | |||
| 31 | Result IReadOnlyApplicationRecordInterface::IsDataCorruptedResult( | ||
| 32 | Out<bool> out_is_data_corrupted_result, Result result) { | ||
| 33 | LOG_WARNING(Service_NS, "(STUBBED) called, result={:#x}", result.GetInnerValue()); | ||
| 34 | *out_is_data_corrupted_result = false; | ||
| 35 | R_SUCCEED(); | ||
| 36 | } | ||
| 37 | |||
| 38 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/read_only_application_record_interface.h b/src/core/hle/service/ns/read_only_application_record_interface.h new file mode 100644 index 000000000..d06e8f5e6 --- /dev/null +++ b/src/core/hle/service/ns/read_only_application_record_interface.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::NS { | ||
| 10 | |||
| 11 | class IReadOnlyApplicationRecordInterface final | ||
| 12 | : public ServiceFramework<IReadOnlyApplicationRecordInterface> { | ||
| 13 | public: | ||
| 14 | explicit IReadOnlyApplicationRecordInterface(Core::System& system_); | ||
| 15 | ~IReadOnlyApplicationRecordInterface() override; | ||
| 16 | |||
| 17 | private: | ||
| 18 | Result HasApplicationRecord(Out<bool> out_has_application_record, u64 program_id); | ||
| 19 | Result IsDataCorruptedResult(Out<bool> out_is_data_corrupted_result, Result result); | ||
| 20 | }; | ||
| 21 | |||
| 22 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/service_getter_interface.cpp b/src/core/hle/service/ns/service_getter_interface.cpp new file mode 100644 index 000000000..1a3dd7166 --- /dev/null +++ b/src/core/hle/service/ns/service_getter_interface.cpp | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/cmif_serialization.h" | ||
| 5 | #include "core/hle/service/ns/account_proxy_interface.h" | ||
| 6 | #include "core/hle/service/ns/application_manager_interface.h" | ||
| 7 | #include "core/hle/service/ns/application_version_interface.h" | ||
| 8 | #include "core/hle/service/ns/content_management_interface.h" | ||
| 9 | #include "core/hle/service/ns/document_interface.h" | ||
| 10 | #include "core/hle/service/ns/download_task_interface.h" | ||
| 11 | #include "core/hle/service/ns/dynamic_rights_interface.h" | ||
| 12 | #include "core/hle/service/ns/ecommerce_interface.h" | ||
| 13 | #include "core/hle/service/ns/factory_reset_interface.h" | ||
| 14 | #include "core/hle/service/ns/read_only_application_control_data_interface.h" | ||
| 15 | #include "core/hle/service/ns/read_only_application_record_interface.h" | ||
| 16 | #include "core/hle/service/ns/service_getter_interface.h" | ||
| 17 | |||
| 18 | namespace Service::NS { | ||
| 19 | |||
| 20 | IServiceGetterInterface::IServiceGetterInterface(Core::System& system_, const char* name) | ||
| 21 | : ServiceFramework{system_, name} { | ||
| 22 | // clang-format off | ||
| 23 | static const FunctionInfo functions[] = { | ||
| 24 | {7988, D<&IServiceGetterInterface::GetDynamicRightsInterface>, "GetDynamicRightsInterface"}, | ||
| 25 | {7989, D<&IServiceGetterInterface::GetReadOnlyApplicationControlDataInterface>, "GetReadOnlyApplicationControlDataInterface"}, | ||
| 26 | {7991, D<&IServiceGetterInterface::GetReadOnlyApplicationRecordInterface>, "GetReadOnlyApplicationRecordInterface"}, | ||
| 27 | {7992, D<&IServiceGetterInterface::GetECommerceInterface>, "GetECommerceInterface"}, | ||
| 28 | {7993, D<&IServiceGetterInterface::GetApplicationVersionInterface>, "GetApplicationVersionInterface"}, | ||
| 29 | {7994, D<&IServiceGetterInterface::GetFactoryResetInterface>, "GetFactoryResetInterface"}, | ||
| 30 | {7995, D<&IServiceGetterInterface::GetAccountProxyInterface>, "GetAccountProxyInterface"}, | ||
| 31 | {7996, D<&IServiceGetterInterface::GetApplicationManagerInterface>, "GetApplicationManagerInterface"}, | ||
| 32 | {7997, D<&IServiceGetterInterface::GetDownloadTaskInterface>, "GetDownloadTaskInterface"}, | ||
| 33 | {7998, D<&IServiceGetterInterface::GetContentManagementInterface>, "GetContentManagementInterface"}, | ||
| 34 | {7999, D<&IServiceGetterInterface::GetDocumentInterface>, "GetDocumentInterface"}, | ||
| 35 | }; | ||
| 36 | // clang-format on | ||
| 37 | |||
| 38 | RegisterHandlers(functions); | ||
| 39 | } | ||
| 40 | |||
| 41 | IServiceGetterInterface::~IServiceGetterInterface() = default; | ||
| 42 | |||
| 43 | Result IServiceGetterInterface::GetDynamicRightsInterface( | ||
| 44 | Out<SharedPointer<IDynamicRightsInterface>> out_interface) { | ||
| 45 | LOG_DEBUG(Service_NS, "called"); | ||
| 46 | *out_interface = std::make_shared<IDynamicRightsInterface>(system); | ||
| 47 | R_SUCCEED(); | ||
| 48 | } | ||
| 49 | |||
| 50 | Result IServiceGetterInterface::GetReadOnlyApplicationControlDataInterface( | ||
| 51 | Out<SharedPointer<IReadOnlyApplicationControlDataInterface>> out_interface) { | ||
| 52 | LOG_DEBUG(Service_NS, "called"); | ||
| 53 | *out_interface = std::make_shared<IReadOnlyApplicationControlDataInterface>(system); | ||
| 54 | R_SUCCEED(); | ||
| 55 | } | ||
| 56 | |||
| 57 | Result IServiceGetterInterface::GetReadOnlyApplicationRecordInterface( | ||
| 58 | Out<SharedPointer<IReadOnlyApplicationRecordInterface>> out_interface) { | ||
| 59 | LOG_DEBUG(Service_NS, "called"); | ||
| 60 | *out_interface = std::make_shared<IReadOnlyApplicationRecordInterface>(system); | ||
| 61 | R_SUCCEED(); | ||
| 62 | } | ||
| 63 | |||
| 64 | Result IServiceGetterInterface::GetECommerceInterface( | ||
| 65 | Out<SharedPointer<IECommerceInterface>> out_interface) { | ||
| 66 | LOG_DEBUG(Service_NS, "called"); | ||
| 67 | *out_interface = std::make_shared<IECommerceInterface>(system); | ||
| 68 | R_SUCCEED(); | ||
| 69 | } | ||
| 70 | |||
| 71 | Result IServiceGetterInterface::GetApplicationVersionInterface( | ||
| 72 | Out<SharedPointer<IApplicationVersionInterface>> out_interface) { | ||
| 73 | LOG_DEBUG(Service_NS, "called"); | ||
| 74 | *out_interface = std::make_shared<IApplicationVersionInterface>(system); | ||
| 75 | R_SUCCEED(); | ||
| 76 | } | ||
| 77 | |||
| 78 | Result IServiceGetterInterface::GetFactoryResetInterface( | ||
| 79 | Out<SharedPointer<IFactoryResetInterface>> out_interface) { | ||
| 80 | LOG_DEBUG(Service_NS, "called"); | ||
| 81 | *out_interface = std::make_shared<IFactoryResetInterface>(system); | ||
| 82 | R_SUCCEED(); | ||
| 83 | } | ||
| 84 | |||
| 85 | Result IServiceGetterInterface::GetAccountProxyInterface( | ||
| 86 | Out<SharedPointer<IAccountProxyInterface>> out_interface) { | ||
| 87 | LOG_DEBUG(Service_NS, "called"); | ||
| 88 | *out_interface = std::make_shared<IAccountProxyInterface>(system); | ||
| 89 | R_SUCCEED(); | ||
| 90 | } | ||
| 91 | |||
| 92 | Result IServiceGetterInterface::GetApplicationManagerInterface( | ||
| 93 | Out<SharedPointer<IApplicationManagerInterface>> out_interface) { | ||
| 94 | LOG_DEBUG(Service_NS, "called"); | ||
| 95 | *out_interface = std::make_shared<IApplicationManagerInterface>(system); | ||
| 96 | R_SUCCEED(); | ||
| 97 | } | ||
| 98 | |||
| 99 | Result IServiceGetterInterface::GetDownloadTaskInterface( | ||
| 100 | Out<SharedPointer<IDownloadTaskInterface>> out_interface) { | ||
| 101 | LOG_DEBUG(Service_NS, "called"); | ||
| 102 | *out_interface = std::make_shared<IDownloadTaskInterface>(system); | ||
| 103 | R_SUCCEED(); | ||
| 104 | } | ||
| 105 | |||
| 106 | Result IServiceGetterInterface::GetContentManagementInterface( | ||
| 107 | Out<SharedPointer<IContentManagementInterface>> out_interface) { | ||
| 108 | LOG_DEBUG(Service_NS, "called"); | ||
| 109 | *out_interface = std::make_shared<IContentManagementInterface>(system); | ||
| 110 | R_SUCCEED(); | ||
| 111 | } | ||
| 112 | |||
| 113 | Result IServiceGetterInterface::GetDocumentInterface( | ||
| 114 | Out<SharedPointer<IDocumentInterface>> out_interface) { | ||
| 115 | LOG_DEBUG(Service_NS, "called"); | ||
| 116 | *out_interface = std::make_shared<IDocumentInterface>(system); | ||
| 117 | R_SUCCEED(); | ||
| 118 | } | ||
| 119 | |||
| 120 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/service_getter_interface.h b/src/core/hle/service/ns/service_getter_interface.h new file mode 100644 index 000000000..bbc18d444 --- /dev/null +++ b/src/core/hle/service/ns/service_getter_interface.h | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::NS { | ||
| 10 | |||
| 11 | class IDynamicRightsInterface; | ||
| 12 | class IReadOnlyApplicationControlDataInterface; | ||
| 13 | class IReadOnlyApplicationRecordInterface; | ||
| 14 | class IECommerceInterface; | ||
| 15 | class IApplicationVersionInterface; | ||
| 16 | class IFactoryResetInterface; | ||
| 17 | class IAccountProxyInterface; | ||
| 18 | class IApplicationManagerInterface; | ||
| 19 | class IDownloadTaskInterface; | ||
| 20 | class IContentManagementInterface; | ||
| 21 | class IDocumentInterface; | ||
| 22 | |||
| 23 | class IServiceGetterInterface : public ServiceFramework<IServiceGetterInterface> { | ||
| 24 | public: | ||
| 25 | explicit IServiceGetterInterface(Core::System& system_, const char* name); | ||
| 26 | ~IServiceGetterInterface() override; | ||
| 27 | |||
| 28 | public: | ||
| 29 | Result GetDynamicRightsInterface(Out<SharedPointer<IDynamicRightsInterface>> out_interface); | ||
| 30 | Result GetReadOnlyApplicationControlDataInterface( | ||
| 31 | Out<SharedPointer<IReadOnlyApplicationControlDataInterface>> out_interface); | ||
| 32 | Result GetReadOnlyApplicationRecordInterface( | ||
| 33 | Out<SharedPointer<IReadOnlyApplicationRecordInterface>> out_interface); | ||
| 34 | Result GetECommerceInterface(Out<SharedPointer<IECommerceInterface>> out_interface); | ||
| 35 | Result GetApplicationVersionInterface( | ||
| 36 | Out<SharedPointer<IApplicationVersionInterface>> out_interface); | ||
| 37 | Result GetFactoryResetInterface(Out<SharedPointer<IFactoryResetInterface>> out_interface); | ||
| 38 | Result GetAccountProxyInterface(Out<SharedPointer<IAccountProxyInterface>> out_interface); | ||
| 39 | Result GetApplicationManagerInterface( | ||
| 40 | Out<SharedPointer<IApplicationManagerInterface>> out_interface); | ||
| 41 | Result GetDownloadTaskInterface(Out<SharedPointer<IDownloadTaskInterface>> out_interface); | ||
| 42 | Result GetContentManagementInterface( | ||
| 43 | Out<SharedPointer<IContentManagementInterface>> out_interface); | ||
| 44 | Result GetDocumentInterface(Out<SharedPointer<IDocumentInterface>> out_interface); | ||
| 45 | }; | ||
| 46 | |||
| 47 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/system_update_control.cpp b/src/core/hle/service/ns/system_update_control.cpp new file mode 100644 index 000000000..f5f5cfd90 --- /dev/null +++ b/src/core/hle/service/ns/system_update_control.cpp | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/cmif_serialization.h" | ||
| 5 | #include "core/hle/service/ns/system_update_control.h" | ||
| 6 | |||
| 7 | namespace Service::NS { | ||
| 8 | |||
| 9 | ISystemUpdateControl::ISystemUpdateControl(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "ISystemUpdateControl"} { | ||
| 11 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | ||
| 13 | {0, nullptr, "HasDownloaded"}, | ||
| 14 | {1, nullptr, "RequestCheckLatestUpdate"}, | ||
| 15 | {2, nullptr, "RequestDownloadLatestUpdate"}, | ||
| 16 | {3, nullptr, "GetDownloadProgress"}, | ||
| 17 | {4, nullptr, "ApplyDownloadedUpdate"}, | ||
| 18 | {5, nullptr, "RequestPrepareCardUpdate"}, | ||
| 19 | {6, nullptr, "GetPrepareCardUpdateProgress"}, | ||
| 20 | {7, nullptr, "HasPreparedCardUpdate"}, | ||
| 21 | {8, nullptr, "ApplyCardUpdate"}, | ||
| 22 | {9, nullptr, "GetDownloadedEulaDataSize"}, | ||
| 23 | {10, nullptr, "GetDownloadedEulaData"}, | ||
| 24 | {11, nullptr, "SetupCardUpdate"}, | ||
| 25 | {12, nullptr, "GetPreparedCardUpdateEulaDataSize"}, | ||
| 26 | {13, nullptr, "GetPreparedCardUpdateEulaData"}, | ||
| 27 | {14, nullptr, "SetupCardUpdateViaSystemUpdater"}, | ||
| 28 | {15, nullptr, "HasReceived"}, | ||
| 29 | {16, nullptr, "RequestReceiveSystemUpdate"}, | ||
| 30 | {17, nullptr, "GetReceiveProgress"}, | ||
| 31 | {18, nullptr, "ApplyReceivedUpdate"}, | ||
| 32 | {19, nullptr, "GetReceivedEulaDataSize"}, | ||
| 33 | {20, nullptr, "GetReceivedEulaData"}, | ||
| 34 | {21, nullptr, "SetupToReceiveSystemUpdate"}, | ||
| 35 | {22, nullptr, "RequestCheckLatestUpdateIncludesRebootlessUpdate"}, | ||
| 36 | }; | ||
| 37 | // clang-format on | ||
| 38 | |||
| 39 | RegisterHandlers(functions); | ||
| 40 | } | ||
| 41 | |||
| 42 | ISystemUpdateControl::~ISystemUpdateControl() = default; | ||
| 43 | |||
| 44 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/system_update_control.h b/src/core/hle/service/ns/system_update_control.h new file mode 100644 index 000000000..a30a09000 --- /dev/null +++ b/src/core/hle/service/ns/system_update_control.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::NS { | ||
| 9 | |||
| 10 | class ISystemUpdateControl final : public ServiceFramework<ISystemUpdateControl> { | ||
| 11 | public: | ||
| 12 | explicit ISystemUpdateControl(Core::System& system_); | ||
| 13 | ~ISystemUpdateControl() override; | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/system_update_interface.cpp b/src/core/hle/service/ns/system_update_interface.cpp new file mode 100644 index 000000000..7e22ca3db --- /dev/null +++ b/src/core/hle/service/ns/system_update_interface.cpp | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/cmif_serialization.h" | ||
| 5 | #include "core/hle/service/ns/system_update_control.h" | ||
| 6 | #include "core/hle/service/ns/system_update_interface.h" | ||
| 7 | |||
| 8 | namespace Service::NS { | ||
| 9 | |||
| 10 | ISystemUpdateInterface::ISystemUpdateInterface(Core::System& system_) | ||
| 11 | : ServiceFramework{system_, "ns:su"}, service_context{system_, "ns:su"}, | ||
| 12 | update_notification_event{service_context} { | ||
| 13 | // clang-format off | ||
| 14 | static const FunctionInfo functions[] = { | ||
| 15 | {0, D<&ISystemUpdateInterface::GetBackgroundNetworkUpdateState>, "GetBackgroundNetworkUpdateState"}, | ||
| 16 | {1, D<&ISystemUpdateInterface::OpenSystemUpdateControl>, "OpenSystemUpdateControl"}, | ||
| 17 | {2, nullptr, "NotifyExFatDriverRequired"}, | ||
| 18 | {3, nullptr, "ClearExFatDriverStatusForDebug"}, | ||
| 19 | {4, nullptr, "RequestBackgroundNetworkUpdate"}, | ||
| 20 | {5, nullptr, "NotifyBackgroundNetworkUpdate"}, | ||
| 21 | {6, nullptr, "NotifyExFatDriverDownloadedForDebug"}, | ||
| 22 | {9, D<&ISystemUpdateInterface::GetSystemUpdateNotificationEventForContentDelivery>, "GetSystemUpdateNotificationEventForContentDelivery"}, | ||
| 23 | {10, nullptr, "NotifySystemUpdateForContentDelivery"}, | ||
| 24 | {11, nullptr, "PrepareShutdown"}, | ||
| 25 | {12, nullptr, "Unknown12"}, | ||
| 26 | {13, nullptr, "Unknown13"}, | ||
| 27 | {14, nullptr, "Unknown14"}, | ||
| 28 | {15, nullptr, "Unknown15"}, | ||
| 29 | {16, nullptr, "DestroySystemUpdateTask"}, | ||
| 30 | {17, nullptr, "RequestSendSystemUpdate"}, | ||
| 31 | {18, nullptr, "GetSendSystemUpdateProgress"}, | ||
| 32 | }; | ||
| 33 | // clang-format on | ||
| 34 | |||
| 35 | RegisterHandlers(functions); | ||
| 36 | } | ||
| 37 | |||
| 38 | ISystemUpdateInterface::~ISystemUpdateInterface() = default; | ||
| 39 | |||
| 40 | Result ISystemUpdateInterface::GetBackgroundNetworkUpdateState( | ||
| 41 | Out<BackgroundNetworkUpdateState> out_background_network_update_state) { | ||
| 42 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 43 | *out_background_network_update_state = BackgroundNetworkUpdateState::None; | ||
| 44 | R_SUCCEED(); | ||
| 45 | } | ||
| 46 | |||
| 47 | Result ISystemUpdateInterface::OpenSystemUpdateControl( | ||
| 48 | Out<SharedPointer<ISystemUpdateControl>> out_system_update_control) { | ||
| 49 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 50 | *out_system_update_control = std::make_shared<ISystemUpdateControl>(system); | ||
| 51 | R_SUCCEED(); | ||
| 52 | } | ||
| 53 | |||
| 54 | Result ISystemUpdateInterface::GetSystemUpdateNotificationEventForContentDelivery( | ||
| 55 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
| 56 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 57 | *out_event = update_notification_event.GetHandle(); | ||
| 58 | R_SUCCEED(); | ||
| 59 | } | ||
| 60 | |||
| 61 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/system_update_interface.h b/src/core/hle/service/ns/system_update_interface.h new file mode 100644 index 000000000..36a2880ec --- /dev/null +++ b/src/core/hle/service/ns/system_update_interface.h | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/kernel_helpers.h" | ||
| 8 | #include "core/hle/service/ns/ns_types.h" | ||
| 9 | #include "core/hle/service/os/event.h" | ||
| 10 | #include "core/hle/service/service.h" | ||
| 11 | |||
| 12 | namespace Kernel { | ||
| 13 | class KReadableEvent; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace Service::NS { | ||
| 17 | |||
| 18 | class ISystemUpdateControl; | ||
| 19 | |||
| 20 | class ISystemUpdateInterface final : public ServiceFramework<ISystemUpdateInterface> { | ||
| 21 | public: | ||
| 22 | explicit ISystemUpdateInterface(Core::System& system_); | ||
| 23 | ~ISystemUpdateInterface() override; | ||
| 24 | |||
| 25 | private: | ||
| 26 | Result GetBackgroundNetworkUpdateState( | ||
| 27 | Out<BackgroundNetworkUpdateState> out_background_network_update_state); | ||
| 28 | Result OpenSystemUpdateControl( | ||
| 29 | Out<SharedPointer<ISystemUpdateControl>> out_system_update_control); | ||
| 30 | Result GetSystemUpdateNotificationEventForContentDelivery( | ||
| 31 | OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
| 32 | |||
| 33 | private: | ||
| 34 | KernelHelpers::ServiceContext service_context; | ||
| 35 | Event update_notification_event; | ||
| 36 | }; | ||
| 37 | |||
| 38 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/vulnerability_manager_interface.cpp b/src/core/hle/service/ns/vulnerability_manager_interface.cpp new file mode 100644 index 000000000..69c21fb89 --- /dev/null +++ b/src/core/hle/service/ns/vulnerability_manager_interface.cpp | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/cmif_serialization.h" | ||
| 5 | #include "core/hle/service/ns/vulnerability_manager_interface.h" | ||
| 6 | |||
| 7 | namespace Service::NS { | ||
| 8 | |||
| 9 | IVulnerabilityManagerInterface::IVulnerabilityManagerInterface(Core::System& system_) | ||
| 10 | : ServiceFramework{system_, "ns:vm"} { | ||
| 11 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | ||
| 13 | {1200, D<&IVulnerabilityManagerInterface::NeedsUpdateVulnerability>, "NeedsUpdateVulnerability"}, | ||
| 14 | {1201, nullptr, "UpdateSafeSystemVersionForDebug"}, | ||
| 15 | {1202, nullptr, "GetSafeSystemVersion"}, | ||
| 16 | }; | ||
| 17 | // clang-format on | ||
| 18 | |||
| 19 | RegisterHandlers(functions); | ||
| 20 | } | ||
| 21 | |||
| 22 | IVulnerabilityManagerInterface::~IVulnerabilityManagerInterface() = default; | ||
| 23 | |||
| 24 | Result IVulnerabilityManagerInterface::NeedsUpdateVulnerability( | ||
| 25 | Out<bool> out_needs_update_vulnerability) { | ||
| 26 | LOG_WARNING(Service_NS, "(STUBBED) called"); | ||
| 27 | *out_needs_update_vulnerability = false; | ||
| 28 | R_SUCCEED(); | ||
| 29 | } | ||
| 30 | |||
| 31 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/vulnerability_manager_interface.h b/src/core/hle/service/ns/vulnerability_manager_interface.h new file mode 100644 index 000000000..c689cf7ec --- /dev/null +++ b/src/core/hle/service/ns/vulnerability_manager_interface.h | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::NS { | ||
| 10 | |||
| 11 | class IVulnerabilityManagerInterface final | ||
| 12 | : public ServiceFramework<IVulnerabilityManagerInterface> { | ||
| 13 | public: | ||
| 14 | explicit IVulnerabilityManagerInterface(Core::System& system_); | ||
| 15 | ~IVulnerabilityManagerInterface() override; | ||
| 16 | |||
| 17 | private: | ||
| 18 | Result NeedsUpdateVulnerability(Out<bool> out_needs_update_vulnerability); | ||
| 19 | }; | ||
| 20 | |||
| 21 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 250d01de3..0265d55f2 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | |||
| @@ -92,11 +92,11 @@ NvResult nvhost_ctrl::IocCtrlEventWait(IocCtrlEventWaitParams& params, bool is_a | |||
| 92 | 92 | ||
| 93 | bool must_unmark_fail = !is_allocation; | 93 | bool must_unmark_fail = !is_allocation; |
| 94 | const u32 event_id = params.value.raw; | 94 | const u32 event_id = params.value.raw; |
| 95 | SCOPE_EXIT({ | 95 | SCOPE_EXIT { |
| 96 | if (must_unmark_fail) { | 96 | if (must_unmark_fail) { |
| 97 | events[event_id].fails = 0; | 97 | events[event_id].fails = 0; |
| 98 | } | 98 | } |
| 99 | }); | 99 | }; |
| 100 | 100 | ||
| 101 | const u32 fence_id = static_cast<u32>(params.fence.id); | 101 | const u32 fence_id = static_cast<u32>(params.fence.id); |
| 102 | 102 | ||
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index cb256e5b4..03eb507b9 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp | |||
| @@ -42,7 +42,7 @@ void EventInterface::FreeEvent(Kernel::KEvent* event) { | |||
| 42 | module.service_context.CloseEvent(event); | 42 | module.service_context.CloseEvent(event); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { | 45 | void LoopProcess(Core::System& system) { |
| 46 | auto server_manager = std::make_unique<ServerManager>(system); | 46 | auto server_manager = std::make_unique<ServerManager>(system); |
| 47 | auto module = std::make_shared<Module>(system); | 47 | auto module = std::make_shared<Module>(system); |
| 48 | const auto NvdrvInterfaceFactoryForApplication = [&, module] { | 48 | const auto NvdrvInterfaceFactoryForApplication = [&, module] { |
| @@ -62,7 +62,6 @@ void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { | |||
| 62 | server_manager->RegisterNamedService("nvdrv:s", NvdrvInterfaceFactoryForSysmodules); | 62 | server_manager->RegisterNamedService("nvdrv:s", NvdrvInterfaceFactoryForSysmodules); |
| 63 | server_manager->RegisterNamedService("nvdrv:t", NvdrvInterfaceFactoryForTesting); | 63 | server_manager->RegisterNamedService("nvdrv:t", NvdrvInterfaceFactoryForTesting); |
| 64 | server_manager->RegisterNamedService("nvmemp", std::make_shared<NVMEMP>(system)); | 64 | server_manager->RegisterNamedService("nvmemp", std::make_shared<NVMEMP>(system)); |
| 65 | nvnflinger.SetNVDrvInstance(module); | ||
| 66 | ServerManager::RunServer(std::move(server_manager)); | 65 | ServerManager::RunServer(std::move(server_manager)); |
| 67 | } | 66 | } |
| 68 | 67 | ||
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index c594f0e5e..b76f81e59 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h | |||
| @@ -10,13 +10,11 @@ | |||
| 10 | #include <span> | 10 | #include <span> |
| 11 | #include <string> | 11 | #include <string> |
| 12 | #include <unordered_map> | 12 | #include <unordered_map> |
| 13 | #include <vector> | ||
| 14 | 13 | ||
| 15 | #include "common/common_types.h" | 14 | #include "common/common_types.h" |
| 16 | #include "core/hle/service/kernel_helpers.h" | 15 | #include "core/hle/service/kernel_helpers.h" |
| 17 | #include "core/hle/service/nvdrv/core/container.h" | 16 | #include "core/hle/service/nvdrv/core/container.h" |
| 18 | #include "core/hle/service/nvdrv/nvdata.h" | 17 | #include "core/hle/service/nvdrv/nvdata.h" |
| 19 | #include "core/hle/service/nvnflinger/ui/fence.h" | ||
| 20 | #include "core/hle/service/service.h" | 18 | #include "core/hle/service/service.h" |
| 21 | 19 | ||
| 22 | namespace Core { | 20 | namespace Core { |
| @@ -27,10 +25,6 @@ namespace Kernel { | |||
| 27 | class KEvent; | 25 | class KEvent; |
| 28 | } | 26 | } |
| 29 | 27 | ||
| 30 | namespace Service::Nvnflinger { | ||
| 31 | class Nvnflinger; | ||
| 32 | } | ||
| 33 | |||
| 34 | namespace Service::Nvidia { | 28 | namespace Service::Nvidia { |
| 35 | 29 | ||
| 36 | namespace NvCore { | 30 | namespace NvCore { |
| @@ -99,7 +93,6 @@ public: | |||
| 99 | 93 | ||
| 100 | private: | 94 | private: |
| 101 | friend class EventInterface; | 95 | friend class EventInterface; |
| 102 | friend class Service::Nvnflinger::Nvnflinger; | ||
| 103 | 96 | ||
| 104 | /// Manages syncpoints on the host | 97 | /// Manages syncpoints on the host |
| 105 | NvCore::Container container; | 98 | NvCore::Container container; |
| @@ -118,6 +111,6 @@ private: | |||
| 118 | std::unordered_map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders; | 111 | std::unordered_map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders; |
| 119 | }; | 112 | }; |
| 120 | 113 | ||
| 121 | void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system); | 114 | void LoopProcess(Core::System& system); |
| 122 | 115 | ||
| 123 | } // namespace Service::Nvidia | 116 | } // namespace Service::Nvidia |
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp index ffe72f281..258970fd5 100644 --- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp +++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp | |||
| @@ -154,10 +154,10 @@ void NVDRV::Close(HLERequestContext& ctx) { | |||
| 154 | void NVDRV::Initialize(HLERequestContext& ctx) { | 154 | void NVDRV::Initialize(HLERequestContext& ctx) { |
| 155 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 155 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 156 | IPC::ResponseBuilder rb{ctx, 3}; | 156 | IPC::ResponseBuilder rb{ctx, 3}; |
| 157 | SCOPE_EXIT({ | 157 | SCOPE_EXIT { |
| 158 | rb.Push(ResultSuccess); | 158 | rb.Push(ResultSuccess); |
| 159 | rb.PushEnum(NvResult::Success); | 159 | rb.PushEnum(NvResult::Success); |
| 160 | }); | 160 | }; |
| 161 | 161 | ||
| 162 | if (is_initialized) { | 162 | if (is_initialized) { |
| 163 | // No need to initialize again | 163 | // No need to initialize again |
| @@ -263,8 +263,10 @@ NVDRV::NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* | |||
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | NVDRV::~NVDRV() { | 265 | NVDRV::~NVDRV() { |
| 266 | auto& container = nvdrv->GetContainer(); | 266 | if (is_initialized) { |
| 267 | container.CloseSession(session_id); | 267 | auto& container = nvdrv->GetContainer(); |
| 268 | container.CloseSession(session_id); | ||
| 269 | } | ||
| 268 | } | 270 | } |
| 269 | 271 | ||
| 270 | } // namespace Service::Nvidia | 272 | } // namespace Service::Nvidia |
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.h b/src/core/hle/service/nvdrv/nvdrv_interface.h index f2195ae1e..c72f92597 100644 --- a/src/core/hle/service/nvdrv/nvdrv_interface.h +++ b/src/core/hle/service/nvdrv/nvdrv_interface.h | |||
| @@ -16,6 +16,10 @@ public: | |||
| 16 | explicit NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* name); | 16 | explicit NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* name); |
| 17 | ~NVDRV() override; | 17 | ~NVDRV() override; |
| 18 | 18 | ||
| 19 | std::shared_ptr<Module> GetModule() const { | ||
| 20 | return nvdrv; | ||
| 21 | } | ||
| 22 | |||
| 19 | private: | 23 | private: |
| 20 | void Open(HLERequestContext& ctx); | 24 | void Open(HLERequestContext& ctx); |
| 21 | void Ioctl1(HLERequestContext& ctx); | 25 | void Ioctl1(HLERequestContext& ctx); |
diff --git a/src/core/hle/service/nvnflinger/binder.h b/src/core/hle/service/nvnflinger/binder.h index 179938192..124accb94 100644 --- a/src/core/hle/service/nvnflinger/binder.h +++ b/src/core/hle/service/nvnflinger/binder.h | |||
| @@ -20,29 +20,12 @@ class HLERequestContext; | |||
| 20 | 20 | ||
| 21 | namespace Service::android { | 21 | namespace Service::android { |
| 22 | 22 | ||
| 23 | enum class TransactionId { | ||
| 24 | RequestBuffer = 1, | ||
| 25 | SetBufferCount = 2, | ||
| 26 | DequeueBuffer = 3, | ||
| 27 | DetachBuffer = 4, | ||
| 28 | DetachNextBuffer = 5, | ||
| 29 | AttachBuffer = 6, | ||
| 30 | QueueBuffer = 7, | ||
| 31 | CancelBuffer = 8, | ||
| 32 | Query = 9, | ||
| 33 | Connect = 10, | ||
| 34 | Disconnect = 11, | ||
| 35 | AllocateBuffers = 13, | ||
| 36 | SetPreallocatedBuffer = 14, | ||
| 37 | GetBufferHistory = 17, | ||
| 38 | }; | ||
| 39 | |||
| 40 | class IBinder { | 23 | class IBinder { |
| 41 | public: | 24 | public: |
| 42 | virtual ~IBinder() = default; | 25 | virtual ~IBinder() = default; |
| 43 | virtual void Transact(android::TransactionId code, u32 flags, std::span<const u8> parcel_data, | 26 | virtual void Transact(u32 code, std::span<const u8> parcel_data, std::span<u8> parcel_reply, |
| 44 | std::span<u8> parcel_reply) = 0; | 27 | u32 flags) = 0; |
| 45 | virtual Kernel::KReadableEvent& GetNativeHandle() = 0; | 28 | virtual Kernel::KReadableEvent* GetNativeHandle(u32 type_id) = 0; |
| 46 | }; | 29 | }; |
| 47 | 30 | ||
| 48 | } // namespace Service::android | 31 | } // namespace Service::android |
diff --git a/src/core/hle/service/nvnflinger/buffer_item_consumer.cpp b/src/core/hle/service/nvnflinger/buffer_item_consumer.cpp index cf151ea3a..123507123 100644 --- a/src/core/hle/service/nvnflinger/buffer_item_consumer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_item_consumer.cpp | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | namespace Service::android { | 13 | namespace Service::android { |
| 14 | 14 | ||
| 15 | BufferItemConsumer::BufferItemConsumer(std::unique_ptr<BufferQueueConsumer> consumer_) | 15 | BufferItemConsumer::BufferItemConsumer(std::shared_ptr<BufferQueueConsumer> consumer_) |
| 16 | : ConsumerBase{std::move(consumer_)} {} | 16 | : ConsumerBase{std::move(consumer_)} {} |
| 17 | 17 | ||
| 18 | Status BufferItemConsumer::AcquireBuffer(BufferItem* item, std::chrono::nanoseconds present_when, | 18 | Status BufferItemConsumer::AcquireBuffer(BufferItem* item, std::chrono::nanoseconds present_when, |
diff --git a/src/core/hle/service/nvnflinger/buffer_item_consumer.h b/src/core/hle/service/nvnflinger/buffer_item_consumer.h index e0c6b3604..9f95c9280 100644 --- a/src/core/hle/service/nvnflinger/buffer_item_consumer.h +++ b/src/core/hle/service/nvnflinger/buffer_item_consumer.h | |||
| @@ -19,7 +19,7 @@ class BufferItem; | |||
| 19 | 19 | ||
| 20 | class BufferItemConsumer final : public ConsumerBase { | 20 | class BufferItemConsumer final : public ConsumerBase { |
| 21 | public: | 21 | public: |
| 22 | explicit BufferItemConsumer(std::unique_ptr<BufferQueueConsumer> consumer); | 22 | explicit BufferItemConsumer(std::shared_ptr<BufferQueueConsumer> consumer); |
| 23 | Status AcquireBuffer(BufferItem* item, std::chrono::nanoseconds present_when, | 23 | Status AcquireBuffer(BufferItem* item, std::chrono::nanoseconds present_when, |
| 24 | bool wait_for_fence = true); | 24 | bool wait_for_fence = true); |
| 25 | Status ReleaseBuffer(const BufferItem& item, const Fence& release_fence); | 25 | Status ReleaseBuffer(const BufferItem& item, const Fence& release_fence); |
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp index bbe8e06d4..3bc23aa97 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp | |||
| @@ -4,12 +4,13 @@ | |||
| 4 | // Parts of this implementation were based on: | 4 | // Parts of this implementation were based on: |
| 5 | // https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueConsumer.cpp | 5 | // https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueConsumer.cpp |
| 6 | 6 | ||
| 7 | #include "common/assert.h" | ||
| 7 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 8 | #include "core/hle/service/nvnflinger/buffer_item.h" | 9 | #include "core/hle/service/nvnflinger/buffer_item.h" |
| 9 | #include "core/hle/service/nvnflinger/buffer_queue_consumer.h" | 10 | #include "core/hle/service/nvnflinger/buffer_queue_consumer.h" |
| 10 | #include "core/hle/service/nvnflinger/buffer_queue_core.h" | 11 | #include "core/hle/service/nvnflinger/buffer_queue_core.h" |
| 12 | #include "core/hle/service/nvnflinger/parcel.h" | ||
| 11 | #include "core/hle/service/nvnflinger/producer_listener.h" | 13 | #include "core/hle/service/nvnflinger/producer_listener.h" |
| 12 | #include "core/hle/service/nvnflinger/ui/graphic_buffer.h" | ||
| 13 | 14 | ||
| 14 | namespace Service::android { | 15 | namespace Service::android { |
| 15 | 16 | ||
| @@ -254,4 +255,77 @@ Status BufferQueueConsumer::GetReleasedBuffers(u64* out_slot_mask) { | |||
| 254 | return Status::NoError; | 255 | return Status::NoError; |
| 255 | } | 256 | } |
| 256 | 257 | ||
| 258 | void BufferQueueConsumer::Transact(u32 code, std::span<const u8> parcel_data, | ||
| 259 | std::span<u8> parcel_reply, u32 flags) { | ||
| 260 | // Values used by BnGraphicBufferConsumer onTransact | ||
| 261 | enum class TransactionId { | ||
| 262 | AcquireBuffer = 1, | ||
| 263 | DetachBuffer = 2, | ||
| 264 | AttachBuffer = 3, | ||
| 265 | ReleaseBuffer = 4, | ||
| 266 | ConsumerConnect = 5, | ||
| 267 | ConsumerDisconnect = 6, | ||
| 268 | GetReleasedBuffers = 7, | ||
| 269 | SetDefaultBufferSize = 8, | ||
| 270 | SetDefaultMaxBufferCount = 9, | ||
| 271 | DisableAsyncBuffer = 10, | ||
| 272 | SetMaxAcquiredBufferCount = 11, | ||
| 273 | SetConsumerName = 12, | ||
| 274 | SetDefaultBufferFormat = 13, | ||
| 275 | SetConsumerUsageBits = 14, | ||
| 276 | SetTransformHint = 15, | ||
| 277 | GetSidebandStream = 16, | ||
| 278 | Unknown18 = 18, | ||
| 279 | Unknown20 = 20, | ||
| 280 | }; | ||
| 281 | |||
| 282 | Status status{Status::NoError}; | ||
| 283 | InputParcel parcel_in{parcel_data}; | ||
| 284 | OutputParcel parcel_out{}; | ||
| 285 | |||
| 286 | switch (static_cast<TransactionId>(code)) { | ||
| 287 | case TransactionId::AcquireBuffer: { | ||
| 288 | BufferItem item; | ||
| 289 | const s64 present_when = parcel_in.Read<s64>(); | ||
| 290 | |||
| 291 | status = AcquireBuffer(&item, std::chrono::nanoseconds{present_when}); | ||
| 292 | |||
| 293 | // TODO: can't write this directly, needs a flattener for the sp<GraphicBuffer> | ||
| 294 | // parcel_out.WriteFlattened(item); | ||
| 295 | UNREACHABLE(); | ||
| 296 | } | ||
| 297 | case TransactionId::ReleaseBuffer: { | ||
| 298 | const s32 slot = parcel_in.Read<s32>(); | ||
| 299 | const u64 frame_number = parcel_in.Read<u64>(); | ||
| 300 | const auto release_fence = parcel_in.ReadFlattened<Fence>(); | ||
| 301 | |||
| 302 | status = ReleaseBuffer(slot, frame_number, release_fence); | ||
| 303 | |||
| 304 | break; | ||
| 305 | } | ||
| 306 | case TransactionId::GetReleasedBuffers: { | ||
| 307 | u64 slot_mask = 0; | ||
| 308 | |||
| 309 | status = GetReleasedBuffers(&slot_mask); | ||
| 310 | |||
| 311 | parcel_out.Write(slot_mask); | ||
| 312 | break; | ||
| 313 | } | ||
| 314 | default: | ||
| 315 | ASSERT_MSG(false, "called, code={} flags={}", code, flags); | ||
| 316 | break; | ||
| 317 | } | ||
| 318 | |||
| 319 | parcel_out.Write(status); | ||
| 320 | |||
| 321 | const auto serialized = parcel_out.Serialize(); | ||
| 322 | std::memcpy(parcel_reply.data(), serialized.data(), | ||
| 323 | std::min(parcel_reply.size(), serialized.size())); | ||
| 324 | } | ||
| 325 | |||
| 326 | Kernel::KReadableEvent* BufferQueueConsumer::GetNativeHandle(u32 type_id) { | ||
| 327 | ASSERT_MSG(false, "called, type_id={}", type_id); | ||
| 328 | return nullptr; | ||
| 329 | } | ||
| 330 | |||
| 257 | } // namespace Service::android | 331 | } // namespace Service::android |
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_consumer.h b/src/core/hle/service/nvnflinger/buffer_queue_consumer.h index 0a61e8dbd..a9226f1c3 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_consumer.h +++ b/src/core/hle/service/nvnflinger/buffer_queue_consumer.h | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <memory> | 10 | #include <memory> |
| 11 | 11 | ||
| 12 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 13 | #include "core/hle/service/nvnflinger/binder.h" | ||
| 13 | #include "core/hle/service/nvnflinger/buffer_queue_defs.h" | 14 | #include "core/hle/service/nvnflinger/buffer_queue_defs.h" |
| 14 | #include "core/hle/service/nvnflinger/status.h" | 15 | #include "core/hle/service/nvnflinger/status.h" |
| 15 | 16 | ||
| @@ -19,10 +20,10 @@ class BufferItem; | |||
| 19 | class BufferQueueCore; | 20 | class BufferQueueCore; |
| 20 | class IConsumerListener; | 21 | class IConsumerListener; |
| 21 | 22 | ||
| 22 | class BufferQueueConsumer final { | 23 | class BufferQueueConsumer final : public IBinder { |
| 23 | public: | 24 | public: |
| 24 | explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_); | 25 | explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_); |
| 25 | ~BufferQueueConsumer(); | 26 | ~BufferQueueConsumer() override; |
| 26 | 27 | ||
| 27 | Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present); | 28 | Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present); |
| 28 | Status ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence); | 29 | Status ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence); |
| @@ -30,6 +31,11 @@ public: | |||
| 30 | Status Disconnect(); | 31 | Status Disconnect(); |
| 31 | Status GetReleasedBuffers(u64* out_slot_mask); | 32 | Status GetReleasedBuffers(u64* out_slot_mask); |
| 32 | 33 | ||
| 34 | void Transact(u32 code, std::span<const u8> parcel_data, std::span<u8> parcel_reply, | ||
| 35 | u32 flags) override; | ||
| 36 | |||
| 37 | Kernel::KReadableEvent* GetNativeHandle(u32 type_id) override; | ||
| 38 | |||
| 33 | private: | 39 | private: |
| 34 | std::shared_ptr<BufferQueueCore> core; | 40 | std::shared_ptr<BufferQueueCore> core; |
| 35 | BufferQueueDefs::SlotsType& slots; | 41 | BufferQueueDefs::SlotsType& slots; |
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp index ec83beb9b..9e5091eeb 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp | |||
| @@ -6,12 +6,9 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 8 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 9 | #include "common/settings.h" | ||
| 10 | #include "core/core.h" | ||
| 11 | #include "core/hle/kernel/k_event.h" | 9 | #include "core/hle/kernel/k_event.h" |
| 12 | #include "core/hle/kernel/k_readable_event.h" | 10 | #include "core/hle/kernel/k_readable_event.h" |
| 13 | #include "core/hle/kernel/kernel.h" | 11 | #include "core/hle/kernel/kernel.h" |
| 14 | #include "core/hle/service/hle_ipc.h" | ||
| 15 | #include "core/hle/service/kernel_helpers.h" | 12 | #include "core/hle/service/kernel_helpers.h" |
| 16 | #include "core/hle/service/nvnflinger/buffer_queue_core.h" | 13 | #include "core/hle/service/nvnflinger/buffer_queue_core.h" |
| 17 | #include "core/hle/service/nvnflinger/buffer_queue_producer.h" | 14 | #include "core/hle/service/nvnflinger/buffer_queue_producer.h" |
| @@ -19,7 +16,6 @@ | |||
| 19 | #include "core/hle/service/nvnflinger/parcel.h" | 16 | #include "core/hle/service/nvnflinger/parcel.h" |
| 20 | #include "core/hle/service/nvnflinger/ui/graphic_buffer.h" | 17 | #include "core/hle/service/nvnflinger/ui/graphic_buffer.h" |
| 21 | #include "core/hle/service/nvnflinger/window.h" | 18 | #include "core/hle/service/nvnflinger/window.h" |
| 22 | #include "core/hle/service/vi/vi.h" | ||
| 23 | 19 | ||
| 24 | namespace Service::android { | 20 | namespace Service::android { |
| 25 | 21 | ||
| @@ -807,13 +803,31 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot, | |||
| 807 | return Status::NoError; | 803 | return Status::NoError; |
| 808 | } | 804 | } |
| 809 | 805 | ||
| 810 | void BufferQueueProducer::Transact(TransactionId code, u32 flags, std::span<const u8> parcel_data, | 806 | void BufferQueueProducer::Transact(u32 code, std::span<const u8> parcel_data, |
| 811 | std::span<u8> parcel_reply) { | 807 | std::span<u8> parcel_reply, u32 flags) { |
| 808 | // Values used by BnGraphicBufferProducer onTransact | ||
| 809 | enum class TransactionId { | ||
| 810 | RequestBuffer = 1, | ||
| 811 | SetBufferCount = 2, | ||
| 812 | DequeueBuffer = 3, | ||
| 813 | DetachBuffer = 4, | ||
| 814 | DetachNextBuffer = 5, | ||
| 815 | AttachBuffer = 6, | ||
| 816 | QueueBuffer = 7, | ||
| 817 | CancelBuffer = 8, | ||
| 818 | Query = 9, | ||
| 819 | Connect = 10, | ||
| 820 | Disconnect = 11, | ||
| 821 | AllocateBuffers = 13, | ||
| 822 | SetPreallocatedBuffer = 14, | ||
| 823 | GetBufferHistory = 17, | ||
| 824 | }; | ||
| 825 | |||
| 812 | Status status{Status::NoError}; | 826 | Status status{Status::NoError}; |
| 813 | InputParcel parcel_in{parcel_data}; | 827 | InputParcel parcel_in{parcel_data}; |
| 814 | OutputParcel parcel_out{}; | 828 | OutputParcel parcel_out{}; |
| 815 | 829 | ||
| 816 | switch (code) { | 830 | switch (static_cast<TransactionId>(code)) { |
| 817 | case TransactionId::Connect: { | 831 | case TransactionId::Connect: { |
| 818 | const auto enable_listener = parcel_in.Read<bool>(); | 832 | const auto enable_listener = parcel_in.Read<bool>(); |
| 819 | const auto api = parcel_in.Read<NativeWindowApi>(); | 833 | const auto api = parcel_in.Read<NativeWindowApi>(); |
| @@ -923,8 +937,8 @@ void BufferQueueProducer::Transact(TransactionId code, u32 flags, std::span<cons | |||
| 923 | std::min(parcel_reply.size(), serialized.size())); | 937 | std::min(parcel_reply.size(), serialized.size())); |
| 924 | } | 938 | } |
| 925 | 939 | ||
| 926 | Kernel::KReadableEvent& BufferQueueProducer::GetNativeHandle() { | 940 | Kernel::KReadableEvent* BufferQueueProducer::GetNativeHandle(u32 type_id) { |
| 927 | return buffer_wait_event->GetReadableEvent(); | 941 | return &buffer_wait_event->GetReadableEvent(); |
| 928 | } | 942 | } |
| 929 | 943 | ||
| 930 | } // namespace Service::android | 944 | } // namespace Service::android |
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.h b/src/core/hle/service/nvnflinger/buffer_queue_producer.h index 4682b0f84..048523514 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.h +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.h | |||
| @@ -45,12 +45,12 @@ public: | |||
| 45 | explicit BufferQueueProducer(Service::KernelHelpers::ServiceContext& service_context_, | 45 | explicit BufferQueueProducer(Service::KernelHelpers::ServiceContext& service_context_, |
| 46 | std::shared_ptr<BufferQueueCore> buffer_queue_core_, | 46 | std::shared_ptr<BufferQueueCore> buffer_queue_core_, |
| 47 | Service::Nvidia::NvCore::NvMap& nvmap_); | 47 | Service::Nvidia::NvCore::NvMap& nvmap_); |
| 48 | ~BufferQueueProducer(); | 48 | ~BufferQueueProducer() override; |
| 49 | 49 | ||
| 50 | void Transact(android::TransactionId code, u32 flags, std::span<const u8> parcel_data, | 50 | void Transact(u32 code, std::span<const u8> parcel_data, std::span<u8> parcel_reply, |
| 51 | std::span<u8> parcel_reply) override; | 51 | u32 flags) override; |
| 52 | 52 | ||
| 53 | Kernel::KReadableEvent& GetNativeHandle() override; | 53 | Kernel::KReadableEvent* GetNativeHandle(u32 type_id) override; |
| 54 | 54 | ||
| 55 | public: | 55 | public: |
| 56 | Status RequestBuffer(s32 slot, std::shared_ptr<GraphicBuffer>* buf); | 56 | Status RequestBuffer(s32 slot, std::shared_ptr<GraphicBuffer>* buf); |
diff --git a/src/core/hle/service/nvnflinger/consumer_base.cpp b/src/core/hle/service/nvnflinger/consumer_base.cpp index 1059e72bf..e360ebfd8 100644 --- a/src/core/hle/service/nvnflinger/consumer_base.cpp +++ b/src/core/hle/service/nvnflinger/consumer_base.cpp | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | namespace Service::android { | 15 | namespace Service::android { |
| 16 | 16 | ||
| 17 | ConsumerBase::ConsumerBase(std::unique_ptr<BufferQueueConsumer> consumer_) | 17 | ConsumerBase::ConsumerBase(std::shared_ptr<BufferQueueConsumer> consumer_) |
| 18 | : consumer{std::move(consumer_)} {} | 18 | : consumer{std::move(consumer_)} {} |
| 19 | 19 | ||
| 20 | ConsumerBase::~ConsumerBase() { | 20 | ConsumerBase::~ConsumerBase() { |
diff --git a/src/core/hle/service/nvnflinger/consumer_base.h b/src/core/hle/service/nvnflinger/consumer_base.h index ea3e9e97a..b29c16f86 100644 --- a/src/core/hle/service/nvnflinger/consumer_base.h +++ b/src/core/hle/service/nvnflinger/consumer_base.h | |||
| @@ -27,7 +27,7 @@ public: | |||
| 27 | void Abandon(); | 27 | void Abandon(); |
| 28 | 28 | ||
| 29 | protected: | 29 | protected: |
| 30 | explicit ConsumerBase(std::unique_ptr<BufferQueueConsumer> consumer_); | 30 | explicit ConsumerBase(std::shared_ptr<BufferQueueConsumer> consumer_); |
| 31 | ~ConsumerBase() override; | 31 | ~ConsumerBase() override; |
| 32 | 32 | ||
| 33 | void OnFrameAvailable(const BufferItem& item) override; | 33 | void OnFrameAvailable(const BufferItem& item) override; |
| @@ -54,7 +54,7 @@ protected: | |||
| 54 | 54 | ||
| 55 | bool is_abandoned{}; | 55 | bool is_abandoned{}; |
| 56 | 56 | ||
| 57 | std::unique_ptr<BufferQueueConsumer> consumer; | 57 | std::shared_ptr<BufferQueueConsumer> consumer; |
| 58 | 58 | ||
| 59 | mutable std::mutex mutex; | 59 | mutable std::mutex mutex; |
| 60 | }; | 60 | }; |
diff --git a/src/core/hle/service/nvnflinger/display.h b/src/core/hle/service/nvnflinger/display.h new file mode 100644 index 000000000..40aa59787 --- /dev/null +++ b/src/core/hle/service/nvnflinger/display.h | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/nvnflinger/buffer_item_consumer.h" | ||
| 7 | #include "core/hle/service/nvnflinger/hwc_layer.h" | ||
| 8 | |||
| 9 | namespace Service::Nvnflinger { | ||
| 10 | |||
| 11 | struct Layer { | ||
| 12 | explicit Layer(std::shared_ptr<android::BufferItemConsumer> buffer_item_consumer_, | ||
| 13 | s32 consumer_id_) | ||
| 14 | : buffer_item_consumer(std::move(buffer_item_consumer_)), consumer_id(consumer_id_), | ||
| 15 | blending(LayerBlending::None), visible(true) {} | ||
| 16 | ~Layer() { | ||
| 17 | buffer_item_consumer->Abandon(); | ||
| 18 | } | ||
| 19 | |||
| 20 | std::shared_ptr<android::BufferItemConsumer> buffer_item_consumer; | ||
| 21 | s32 consumer_id; | ||
| 22 | LayerBlending blending; | ||
| 23 | bool visible; | ||
| 24 | }; | ||
| 25 | |||
| 26 | struct LayerStack { | ||
| 27 | std::vector<std::shared_ptr<Layer>> layers; | ||
| 28 | |||
| 29 | std::shared_ptr<Layer> FindLayer(s32 consumer_id) { | ||
| 30 | for (auto& layer : layers) { | ||
| 31 | if (layer->consumer_id == consumer_id) { | ||
| 32 | return layer; | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | return nullptr; | ||
| 37 | } | ||
| 38 | |||
| 39 | bool HasLayers() { | ||
| 40 | return !layers.empty(); | ||
| 41 | } | ||
| 42 | }; | ||
| 43 | |||
| 44 | struct Display { | ||
| 45 | explicit Display(u64 id_) { | ||
| 46 | id = id_; | ||
| 47 | } | ||
| 48 | |||
| 49 | u64 id; | ||
| 50 | LayerStack stack; | ||
| 51 | }; | ||
| 52 | |||
| 53 | } // namespace Service::Nvnflinger | ||
diff --git a/src/core/hle/service/nvnflinger/hardware_composer.cpp b/src/core/hle/service/nvnflinger/hardware_composer.cpp index be7eb97a3..f2dfe85a9 100644 --- a/src/core/hle/service/nvnflinger/hardware_composer.cpp +++ b/src/core/hle/service/nvnflinger/hardware_composer.cpp | |||
| @@ -10,8 +10,6 @@ | |||
| 10 | #include "core/hle/service/nvnflinger/hardware_composer.h" | 10 | #include "core/hle/service/nvnflinger/hardware_composer.h" |
| 11 | #include "core/hle/service/nvnflinger/hwc_layer.h" | 11 | #include "core/hle/service/nvnflinger/hwc_layer.h" |
| 12 | #include "core/hle/service/nvnflinger/ui/graphic_buffer.h" | 12 | #include "core/hle/service/nvnflinger/ui/graphic_buffer.h" |
| 13 | #include "core/hle/service/vi/display/vi_display.h" | ||
| 14 | #include "core/hle/service/vi/layer/vi_layer.h" | ||
| 15 | 13 | ||
| 16 | namespace Service::Nvnflinger { | 14 | namespace Service::Nvnflinger { |
| 17 | 15 | ||
| @@ -44,7 +42,7 @@ s32 NormalizeSwapInterval(f32* out_speed_scale, s32 swap_interval) { | |||
| 44 | HardwareComposer::HardwareComposer() = default; | 42 | HardwareComposer::HardwareComposer() = default; |
| 45 | HardwareComposer::~HardwareComposer() = default; | 43 | HardwareComposer::~HardwareComposer() = default; |
| 46 | 44 | ||
| 47 | u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, VI::Display& display, | 45 | u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display, |
| 48 | Nvidia::Devices::nvdisp_disp0& nvdisp) { | 46 | Nvidia::Devices::nvdisp_disp0& nvdisp) { |
| 49 | boost::container::small_vector<HwcLayer, 2> composition_stack; | 47 | boost::container::small_vector<HwcLayer, 2> composition_stack; |
| 50 | 48 | ||
| @@ -56,12 +54,11 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, VI::Display& display, | |||
| 56 | bool has_acquired_buffer{}; | 54 | bool has_acquired_buffer{}; |
| 57 | 55 | ||
| 58 | // Acquire all necessary framebuffers. | 56 | // Acquire all necessary framebuffers. |
| 59 | for (size_t i = 0; i < display.GetNumLayers(); i++) { | 57 | for (auto& layer : display.stack.layers) { |
| 60 | auto& layer = display.GetLayer(i); | 58 | auto consumer_id = layer->consumer_id; |
| 61 | auto layer_id = layer.GetLayerId(); | ||
| 62 | 59 | ||
| 63 | // Try to fetch the framebuffer (either new or stale). | 60 | // Try to fetch the framebuffer (either new or stale). |
| 64 | const auto result = this->CacheFramebufferLocked(layer, layer_id); | 61 | const auto result = this->CacheFramebufferLocked(*layer, consumer_id); |
| 65 | 62 | ||
| 66 | // If we failed, skip this layer. | 63 | // If we failed, skip this layer. |
| 67 | if (result == CacheStatus::NoBufferAvailable) { | 64 | if (result == CacheStatus::NoBufferAvailable) { |
| @@ -73,24 +70,26 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, VI::Display& display, | |||
| 73 | has_acquired_buffer = true; | 70 | has_acquired_buffer = true; |
| 74 | } | 71 | } |
| 75 | 72 | ||
| 76 | const auto& buffer = m_framebuffers[layer_id]; | 73 | const auto& buffer = m_framebuffers[consumer_id]; |
| 77 | const auto& item = buffer.item; | 74 | const auto& item = buffer.item; |
| 78 | const auto& igbp_buffer = *item.graphic_buffer; | 75 | const auto& igbp_buffer = *item.graphic_buffer; |
| 79 | 76 | ||
| 80 | // TODO: get proper Z-index from layer | 77 | // TODO: get proper Z-index from layer |
| 81 | composition_stack.emplace_back(HwcLayer{ | 78 | if (layer->visible) { |
| 82 | .buffer_handle = igbp_buffer.BufferId(), | 79 | composition_stack.emplace_back(HwcLayer{ |
| 83 | .offset = igbp_buffer.Offset(), | 80 | .buffer_handle = igbp_buffer.BufferId(), |
| 84 | .format = igbp_buffer.ExternalFormat(), | 81 | .offset = igbp_buffer.Offset(), |
| 85 | .width = igbp_buffer.Width(), | 82 | .format = igbp_buffer.ExternalFormat(), |
| 86 | .height = igbp_buffer.Height(), | 83 | .width = igbp_buffer.Width(), |
| 87 | .stride = igbp_buffer.Stride(), | 84 | .height = igbp_buffer.Height(), |
| 88 | .z_index = 0, | 85 | .stride = igbp_buffer.Stride(), |
| 89 | .blending = layer.GetBlending(), | 86 | .z_index = 0, |
| 90 | .transform = static_cast<android::BufferTransformFlags>(item.transform), | 87 | .blending = layer->blending, |
| 91 | .crop_rect = item.crop, | 88 | .transform = static_cast<android::BufferTransformFlags>(item.transform), |
| 92 | .acquire_fence = item.fence, | 89 | .crop_rect = item.crop, |
| 93 | }); | 90 | .acquire_fence = item.fence, |
| 91 | }); | ||
| 92 | } | ||
| 94 | 93 | ||
| 95 | // We need to compose again either before this frame is supposed to | 94 | // We need to compose again either before this frame is supposed to |
| 96 | // be released, or exactly on the vsync period it should be released. | 95 | // be released, or exactly on the vsync period it should be released. |
| @@ -135,10 +134,10 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, VI::Display& display, | |||
| 135 | continue; | 134 | continue; |
| 136 | } | 135 | } |
| 137 | 136 | ||
| 138 | if (auto* layer = display.FindLayer(layer_id); layer != nullptr) { | 137 | if (const auto layer = display.stack.FindLayer(layer_id); layer != nullptr) { |
| 139 | // TODO: support release fence | 138 | // TODO: support release fence |
| 140 | // This is needed to prevent screen tearing | 139 | // This is needed to prevent screen tearing |
| 141 | layer->GetConsumer().ReleaseBuffer(framebuffer.item, android::Fence::NoFence()); | 140 | layer->buffer_item_consumer->ReleaseBuffer(framebuffer.item, android::Fence::NoFence()); |
| 142 | framebuffer.is_acquired = false; | 141 | framebuffer.is_acquired = false; |
| 143 | } | 142 | } |
| 144 | } | 143 | } |
| @@ -146,26 +145,26 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, VI::Display& display, | |||
| 146 | return frame_advance; | 145 | return frame_advance; |
| 147 | } | 146 | } |
| 148 | 147 | ||
| 149 | void HardwareComposer::RemoveLayerLocked(VI::Display& display, LayerId layer_id) { | 148 | void HardwareComposer::RemoveLayerLocked(Display& display, ConsumerId consumer_id) { |
| 150 | // Check if we are tracking a slot with this layer_id. | 149 | // Check if we are tracking a slot with this consumer_id. |
| 151 | const auto it = m_framebuffers.find(layer_id); | 150 | const auto it = m_framebuffers.find(consumer_id); |
| 152 | if (it == m_framebuffers.end()) { | 151 | if (it == m_framebuffers.end()) { |
| 153 | return; | 152 | return; |
| 154 | } | 153 | } |
| 155 | 154 | ||
| 156 | // Try to release the buffer item. | 155 | // Try to release the buffer item. |
| 157 | auto* const layer = display.FindLayer(layer_id); | 156 | const auto layer = display.stack.FindLayer(consumer_id); |
| 158 | if (layer && it->second.is_acquired) { | 157 | if (layer && it->second.is_acquired) { |
| 159 | layer->GetConsumer().ReleaseBuffer(it->second.item, android::Fence::NoFence()); | 158 | layer->buffer_item_consumer->ReleaseBuffer(it->second.item, android::Fence::NoFence()); |
| 160 | } | 159 | } |
| 161 | 160 | ||
| 162 | // Erase the slot. | 161 | // Erase the slot. |
| 163 | m_framebuffers.erase(it); | 162 | m_framebuffers.erase(it); |
| 164 | } | 163 | } |
| 165 | 164 | ||
| 166 | bool HardwareComposer::TryAcquireFramebufferLocked(VI::Layer& layer, Framebuffer& framebuffer) { | 165 | bool HardwareComposer::TryAcquireFramebufferLocked(Layer& layer, Framebuffer& framebuffer) { |
| 167 | // Attempt the update. | 166 | // Attempt the update. |
| 168 | const auto status = layer.GetConsumer().AcquireBuffer(&framebuffer.item, {}, false); | 167 | const auto status = layer.buffer_item_consumer->AcquireBuffer(&framebuffer.item, {}, false); |
| 169 | if (status != android::Status::NoError) { | 168 | if (status != android::Status::NoError) { |
| 170 | return false; | 169 | return false; |
| 171 | } | 170 | } |
| @@ -178,10 +177,10 @@ bool HardwareComposer::TryAcquireFramebufferLocked(VI::Layer& layer, Framebuffer | |||
| 178 | return true; | 177 | return true; |
| 179 | } | 178 | } |
| 180 | 179 | ||
| 181 | HardwareComposer::CacheStatus HardwareComposer::CacheFramebufferLocked(VI::Layer& layer, | 180 | HardwareComposer::CacheStatus HardwareComposer::CacheFramebufferLocked(Layer& layer, |
| 182 | LayerId layer_id) { | 181 | ConsumerId consumer_id) { |
| 183 | // Check if this framebuffer is already present. | 182 | // Check if this framebuffer is already present. |
| 184 | const auto it = m_framebuffers.find(layer_id); | 183 | const auto it = m_framebuffers.find(consumer_id); |
| 185 | if (it != m_framebuffers.end()) { | 184 | if (it != m_framebuffers.end()) { |
| 186 | // If it's currently still acquired, we are done. | 185 | // If it's currently still acquired, we are done. |
| 187 | if (it->second.is_acquired) { | 186 | if (it->second.is_acquired) { |
| @@ -203,7 +202,7 @@ HardwareComposer::CacheStatus HardwareComposer::CacheFramebufferLocked(VI::Layer | |||
| 203 | 202 | ||
| 204 | if (this->TryAcquireFramebufferLocked(layer, framebuffer)) { | 203 | if (this->TryAcquireFramebufferLocked(layer, framebuffer)) { |
| 205 | // Move the buffer item into a new slot. | 204 | // Move the buffer item into a new slot. |
| 206 | m_framebuffers.emplace(layer_id, std::move(framebuffer)); | 205 | m_framebuffers.emplace(consumer_id, std::move(framebuffer)); |
| 207 | 206 | ||
| 208 | // We succeeded. | 207 | // We succeeded. |
| 209 | return CacheStatus::BufferAcquired; | 208 | return CacheStatus::BufferAcquired; |
diff --git a/src/core/hle/service/nvnflinger/hardware_composer.h b/src/core/hle/service/nvnflinger/hardware_composer.h index 28392c512..c5b830468 100644 --- a/src/core/hle/service/nvnflinger/hardware_composer.h +++ b/src/core/hle/service/nvnflinger/hardware_composer.h | |||
| @@ -3,35 +3,29 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <memory> | ||
| 7 | #include <boost/container/flat_map.hpp> | 6 | #include <boost/container/flat_map.hpp> |
| 8 | 7 | ||
| 9 | #include "core/hle/service/nvnflinger/buffer_item.h" | 8 | #include "core/hle/service/nvnflinger/buffer_item.h" |
| 9 | #include "core/hle/service/nvnflinger/display.h" | ||
| 10 | 10 | ||
| 11 | namespace Service::Nvidia::Devices { | 11 | namespace Service::Nvidia::Devices { |
| 12 | class nvdisp_disp0; | 12 | class nvdisp_disp0; |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | namespace Service::VI { | ||
| 16 | class Display; | ||
| 17 | class Layer; | ||
| 18 | } // namespace Service::VI | ||
| 19 | |||
| 20 | namespace Service::Nvnflinger { | 15 | namespace Service::Nvnflinger { |
| 21 | 16 | ||
| 22 | using LayerId = u64; | 17 | using ConsumerId = s32; |
| 23 | 18 | ||
| 24 | class HardwareComposer { | 19 | class HardwareComposer { |
| 25 | public: | 20 | public: |
| 26 | explicit HardwareComposer(); | 21 | explicit HardwareComposer(); |
| 27 | ~HardwareComposer(); | 22 | ~HardwareComposer(); |
| 28 | 23 | ||
| 29 | u32 ComposeLocked(f32* out_speed_scale, VI::Display& display, | 24 | u32 ComposeLocked(f32* out_speed_scale, Display& display, |
| 30 | Nvidia::Devices::nvdisp_disp0& nvdisp); | 25 | Nvidia::Devices::nvdisp_disp0& nvdisp); |
| 31 | void RemoveLayerLocked(VI::Display& display, LayerId layer_id); | 26 | void RemoveLayerLocked(Display& display, ConsumerId consumer_id); |
| 32 | 27 | ||
| 33 | private: | 28 | private: |
| 34 | // TODO: do we want to track frame number in vi instead? | ||
| 35 | u64 m_frame_number{0}; | 29 | u64 m_frame_number{0}; |
| 36 | 30 | ||
| 37 | private: | 31 | private: |
| @@ -49,11 +43,11 @@ private: | |||
| 49 | CachedBufferReused, | 43 | CachedBufferReused, |
| 50 | }; | 44 | }; |
| 51 | 45 | ||
| 52 | boost::container::flat_map<LayerId, Framebuffer> m_framebuffers{}; | 46 | boost::container::flat_map<ConsumerId, Framebuffer> m_framebuffers{}; |
| 53 | 47 | ||
| 54 | private: | 48 | private: |
| 55 | bool TryAcquireFramebufferLocked(VI::Layer& layer, Framebuffer& framebuffer); | 49 | bool TryAcquireFramebufferLocked(Layer& layer, Framebuffer& framebuffer); |
| 56 | CacheStatus CacheFramebufferLocked(VI::Layer& layer, LayerId layer_id); | 50 | CacheStatus CacheFramebufferLocked(Layer& layer, ConsumerId consumer_id); |
| 57 | }; | 51 | }; |
| 58 | 52 | ||
| 59 | } // namespace Service::Nvnflinger | 53 | } // namespace Service::Nvnflinger |
diff --git a/src/core/hle/service/vi/hos_binder_driver.cpp b/src/core/hle/service/nvnflinger/hos_binder_driver.cpp index ba0317245..8629a2e89 100644 --- a/src/core/hle/service/vi/hos_binder_driver.cpp +++ b/src/core/hle/service/nvnflinger/hos_binder_driver.cpp | |||
| @@ -3,13 +3,16 @@ | |||
| 3 | 3 | ||
| 4 | #include "core/hle/service/cmif_serialization.h" | 4 | #include "core/hle/service/cmif_serialization.h" |
| 5 | #include "core/hle/service/nvnflinger/binder.h" | 5 | #include "core/hle/service/nvnflinger/binder.h" |
| 6 | #include "core/hle/service/nvnflinger/hos_binder_driver.h" | ||
| 6 | #include "core/hle/service/nvnflinger/hos_binder_driver_server.h" | 7 | #include "core/hle/service/nvnflinger/hos_binder_driver_server.h" |
| 7 | #include "core/hle/service/vi/hos_binder_driver.h" | ||
| 8 | 8 | ||
| 9 | namespace Service::VI { | 9 | namespace Service::Nvnflinger { |
| 10 | 10 | ||
| 11 | IHOSBinderDriver::IHOSBinderDriver(Core::System& system_, Nvnflinger::HosBinderDriverServer& server) | 11 | IHOSBinderDriver::IHOSBinderDriver(Core::System& system_, |
| 12 | : ServiceFramework{system_, "IHOSBinderDriver"}, m_server(server) { | 12 | std::shared_ptr<HosBinderDriverServer> server, |
| 13 | std::shared_ptr<SurfaceFlinger> surface_flinger) | ||
| 14 | : ServiceFramework{system_, "IHOSBinderDriver"}, m_server(server), | ||
| 15 | m_surface_flinger(surface_flinger) { | ||
| 13 | static const FunctionInfo functions[] = { | 16 | static const FunctionInfo functions[] = { |
| 14 | {0, C<&IHOSBinderDriver::TransactParcel>, "TransactParcel"}, | 17 | {0, C<&IHOSBinderDriver::TransactParcel>, "TransactParcel"}, |
| 15 | {1, C<&IHOSBinderDriver::AdjustRefcount>, "AdjustRefcount"}, | 18 | {1, C<&IHOSBinderDriver::AdjustRefcount>, "AdjustRefcount"}, |
| @@ -21,13 +24,18 @@ IHOSBinderDriver::IHOSBinderDriver(Core::System& system_, Nvnflinger::HosBinderD | |||
| 21 | 24 | ||
| 22 | IHOSBinderDriver::~IHOSBinderDriver() = default; | 25 | IHOSBinderDriver::~IHOSBinderDriver() = default; |
| 23 | 26 | ||
| 24 | Result IHOSBinderDriver::TransactParcel(s32 binder_id, android::TransactionId transaction_id, | 27 | Result IHOSBinderDriver::TransactParcel(s32 binder_id, u32 transaction_id, |
| 25 | InBuffer<BufferAttr_HipcMapAlias> parcel_data, | 28 | InBuffer<BufferAttr_HipcMapAlias> parcel_data, |
| 26 | OutBuffer<BufferAttr_HipcMapAlias> parcel_reply, | 29 | OutBuffer<BufferAttr_HipcMapAlias> parcel_reply, |
| 27 | u32 flags) { | 30 | u32 flags) { |
| 28 | LOG_DEBUG(Service_VI, "called. id={} transaction={}, flags={}", binder_id, transaction_id, | 31 | LOG_DEBUG(Service_VI, "called. id={} transaction={}, flags={}", binder_id, transaction_id, |
| 29 | flags); | 32 | flags); |
| 30 | m_server.TryGetProducer(binder_id)->Transact(transaction_id, flags, parcel_data, parcel_reply); | 33 | |
| 34 | const auto binder = m_server->TryGetBinder(binder_id); | ||
| 35 | R_SUCCEED_IF(binder == nullptr); | ||
| 36 | |||
| 37 | binder->Transact(transaction_id, parcel_data, parcel_reply, flags); | ||
| 38 | |||
| 31 | R_SUCCEED(); | 39 | R_SUCCEED(); |
| 32 | } | 40 | } |
| 33 | 41 | ||
| @@ -39,15 +47,20 @@ Result IHOSBinderDriver::AdjustRefcount(s32 binder_id, s32 addval, s32 type) { | |||
| 39 | Result IHOSBinderDriver::GetNativeHandle(s32 binder_id, u32 type_id, | 47 | Result IHOSBinderDriver::GetNativeHandle(s32 binder_id, u32 type_id, |
| 40 | OutCopyHandle<Kernel::KReadableEvent> out_handle) { | 48 | OutCopyHandle<Kernel::KReadableEvent> out_handle) { |
| 41 | LOG_WARNING(Service_VI, "(STUBBED) called id={}, type_id={}", binder_id, type_id); | 49 | LOG_WARNING(Service_VI, "(STUBBED) called id={}, type_id={}", binder_id, type_id); |
| 42 | *out_handle = &m_server.TryGetProducer(binder_id)->GetNativeHandle(); | 50 | |
| 51 | const auto binder = m_server->TryGetBinder(binder_id); | ||
| 52 | R_UNLESS(binder != nullptr, ResultUnknown); | ||
| 53 | |||
| 54 | *out_handle = binder->GetNativeHandle(type_id); | ||
| 55 | |||
| 43 | R_SUCCEED(); | 56 | R_SUCCEED(); |
| 44 | } | 57 | } |
| 45 | 58 | ||
| 46 | Result IHOSBinderDriver::TransactParcelAuto(s32 binder_id, android::TransactionId transaction_id, | 59 | Result IHOSBinderDriver::TransactParcelAuto(s32 binder_id, u32 transaction_id, |
| 47 | InBuffer<BufferAttr_HipcAutoSelect> parcel_data, | 60 | InBuffer<BufferAttr_HipcAutoSelect> parcel_data, |
| 48 | OutBuffer<BufferAttr_HipcAutoSelect> parcel_reply, | 61 | OutBuffer<BufferAttr_HipcAutoSelect> parcel_reply, |
| 49 | u32 flags) { | 62 | u32 flags) { |
| 50 | R_RETURN(this->TransactParcel(binder_id, transaction_id, parcel_data, parcel_reply, flags)); | 63 | R_RETURN(this->TransactParcel(binder_id, transaction_id, parcel_data, parcel_reply, flags)); |
| 51 | } | 64 | } |
| 52 | 65 | ||
| 53 | } // namespace Service::VI | 66 | } // namespace Service::Nvnflinger |
diff --git a/src/core/hle/service/vi/hos_binder_driver.h b/src/core/hle/service/nvnflinger/hos_binder_driver.h index ed6e8cdbe..b7fb07bd2 100644 --- a/src/core/hle/service/vi/hos_binder_driver.h +++ b/src/core/hle/service/nvnflinger/hos_binder_driver.h | |||
| @@ -2,29 +2,45 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/cmif_types.h" | 4 | #include "core/hle/service/cmif_types.h" |
| 5 | #include "core/hle/service/nvnflinger/binder.h" | ||
| 6 | #include "core/hle/service/service.h" | 5 | #include "core/hle/service/service.h" |
| 7 | 6 | ||
| 8 | namespace Service::VI { | 7 | namespace Kernel { |
| 8 | class KReadableEvent; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::Nvnflinger { | ||
| 12 | |||
| 13 | class HosBinderDriverServer; | ||
| 14 | class SurfaceFlinger; | ||
| 9 | 15 | ||
| 10 | class IHOSBinderDriver final : public ServiceFramework<IHOSBinderDriver> { | 16 | class IHOSBinderDriver final : public ServiceFramework<IHOSBinderDriver> { |
| 11 | public: | 17 | public: |
| 12 | explicit IHOSBinderDriver(Core::System& system_, Nvnflinger::HosBinderDriverServer& server); | 18 | explicit IHOSBinderDriver(Core::System& system_, std::shared_ptr<HosBinderDriverServer> server, |
| 19 | std::shared_ptr<SurfaceFlinger> surface_flinger); | ||
| 13 | ~IHOSBinderDriver() override; | 20 | ~IHOSBinderDriver() override; |
| 14 | 21 | ||
| 22 | std::shared_ptr<SurfaceFlinger> GetSurfaceFlinger() { | ||
| 23 | return m_surface_flinger; | ||
| 24 | } | ||
| 25 | |||
| 26 | std::shared_ptr<HosBinderDriverServer> GetServer() { | ||
| 27 | return m_server; | ||
| 28 | } | ||
| 29 | |||
| 15 | private: | 30 | private: |
| 16 | Result TransactParcel(s32 binder_id, android::TransactionId transaction_id, | 31 | Result TransactParcel(s32 binder_id, u32 transaction_id, |
| 17 | InBuffer<BufferAttr_HipcMapAlias> parcel_data, | 32 | InBuffer<BufferAttr_HipcMapAlias> parcel_data, |
| 18 | OutBuffer<BufferAttr_HipcMapAlias> parcel_reply, u32 flags); | 33 | OutBuffer<BufferAttr_HipcMapAlias> parcel_reply, u32 flags); |
| 19 | Result AdjustRefcount(s32 binder_id, s32 addval, s32 type); | 34 | Result AdjustRefcount(s32 binder_id, s32 addval, s32 type); |
| 20 | Result GetNativeHandle(s32 binder_id, u32 type_id, | 35 | Result GetNativeHandle(s32 binder_id, u32 type_id, |
| 21 | OutCopyHandle<Kernel::KReadableEvent> out_handle); | 36 | OutCopyHandle<Kernel::KReadableEvent> out_handle); |
| 22 | Result TransactParcelAuto(s32 binder_id, android::TransactionId transaction_id, | 37 | Result TransactParcelAuto(s32 binder_id, u32 transaction_id, |
| 23 | InBuffer<BufferAttr_HipcAutoSelect> parcel_data, | 38 | InBuffer<BufferAttr_HipcAutoSelect> parcel_data, |
| 24 | OutBuffer<BufferAttr_HipcAutoSelect> parcel_reply, u32 flags); | 39 | OutBuffer<BufferAttr_HipcAutoSelect> parcel_reply, u32 flags); |
| 25 | 40 | ||
| 26 | private: | 41 | private: |
| 27 | Nvnflinger::HosBinderDriverServer& m_server; | 42 | const std::shared_ptr<HosBinderDriverServer> m_server; |
| 43 | const std::shared_ptr<SurfaceFlinger> m_surface_flinger; | ||
| 28 | }; | 44 | }; |
| 29 | 45 | ||
| 30 | } // namespace Service::VI | 46 | } // namespace Service::Nvnflinger |
diff --git a/src/core/hle/service/nvnflinger/hos_binder_driver_server.cpp b/src/core/hle/service/nvnflinger/hos_binder_driver_server.cpp index b86a79ec9..29addda44 100644 --- a/src/core/hle/service/nvnflinger/hos_binder_driver_server.cpp +++ b/src/core/hle/service/nvnflinger/hos_binder_driver_server.cpp | |||
| @@ -8,26 +8,30 @@ | |||
| 8 | 8 | ||
| 9 | namespace Service::Nvnflinger { | 9 | namespace Service::Nvnflinger { |
| 10 | 10 | ||
| 11 | HosBinderDriverServer::HosBinderDriverServer(Core::System& system_) | 11 | HosBinderDriverServer::HosBinderDriverServer() = default; |
| 12 | : service_context(system_, "HosBinderDriverServer") {} | 12 | HosBinderDriverServer::~HosBinderDriverServer() = default; |
| 13 | 13 | ||
| 14 | HosBinderDriverServer::~HosBinderDriverServer() {} | 14 | s32 HosBinderDriverServer::RegisterBinder(std::shared_ptr<android::IBinder>&& binder) { |
| 15 | |||
| 16 | u64 HosBinderDriverServer::RegisterProducer(std::unique_ptr<android::IBinder>&& binder) { | ||
| 17 | std::scoped_lock lk{lock}; | 15 | std::scoped_lock lk{lock}; |
| 18 | 16 | ||
| 19 | last_id++; | 17 | last_id++; |
| 20 | 18 | ||
| 21 | producers[last_id] = std::move(binder); | 19 | binders[last_id] = std::move(binder); |
| 22 | 20 | ||
| 23 | return last_id; | 21 | return last_id; |
| 24 | } | 22 | } |
| 25 | 23 | ||
| 26 | android::IBinder* HosBinderDriverServer::TryGetProducer(u64 id) { | 24 | void HosBinderDriverServer::UnregisterBinder(s32 binder_id) { |
| 25 | std::scoped_lock lk{lock}; | ||
| 26 | |||
| 27 | binders.erase(binder_id); | ||
| 28 | } | ||
| 29 | |||
| 30 | std::shared_ptr<android::IBinder> HosBinderDriverServer::TryGetBinder(s32 id) const { | ||
| 27 | std::scoped_lock lk{lock}; | 31 | std::scoped_lock lk{lock}; |
| 28 | 32 | ||
| 29 | if (auto search = producers.find(id); search != producers.end()) { | 33 | if (auto search = binders.find(id); search != binders.end()) { |
| 30 | return search->second.get(); | 34 | return search->second; |
| 31 | } | 35 | } |
| 32 | 36 | ||
| 33 | return {}; | 37 | return {}; |
diff --git a/src/core/hle/service/nvnflinger/hos_binder_driver_server.h b/src/core/hle/service/nvnflinger/hos_binder_driver_server.h index 58bb9469a..d72b50833 100644 --- a/src/core/hle/service/nvnflinger/hos_binder_driver_server.h +++ b/src/core/hle/service/nvnflinger/hos_binder_driver_server.h | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | #include <unordered_map> | 8 | #include <unordered_map> |
| 9 | 9 | ||
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "core/hle/service/kernel_helpers.h" | ||
| 12 | #include "core/hle/service/nvnflinger/binder.h" | 11 | #include "core/hle/service/nvnflinger/binder.h" |
| 13 | 12 | ||
| 14 | namespace Core { | 13 | namespace Core { |
| @@ -19,19 +18,18 @@ namespace Service::Nvnflinger { | |||
| 19 | 18 | ||
| 20 | class HosBinderDriverServer final { | 19 | class HosBinderDriverServer final { |
| 21 | public: | 20 | public: |
| 22 | explicit HosBinderDriverServer(Core::System& system_); | 21 | explicit HosBinderDriverServer(); |
| 23 | ~HosBinderDriverServer(); | 22 | ~HosBinderDriverServer(); |
| 24 | 23 | ||
| 25 | u64 RegisterProducer(std::unique_ptr<android::IBinder>&& binder); | 24 | s32 RegisterBinder(std::shared_ptr<android::IBinder>&& binder); |
| 25 | void UnregisterBinder(s32 binder_id); | ||
| 26 | 26 | ||
| 27 | android::IBinder* TryGetProducer(u64 id); | 27 | std::shared_ptr<android::IBinder> TryGetBinder(s32 id) const; |
| 28 | 28 | ||
| 29 | private: | 29 | private: |
| 30 | KernelHelpers::ServiceContext service_context; | 30 | std::unordered_map<s32, std::shared_ptr<android::IBinder>> binders; |
| 31 | 31 | mutable std::mutex lock; | |
| 32 | std::unordered_map<u64, std::unique_ptr<android::IBinder>> producers; | 32 | s32 last_id{}; |
| 33 | std::mutex lock; | ||
| 34 | u64 last_id{}; | ||
| 35 | }; | 33 | }; |
| 36 | 34 | ||
| 37 | } // namespace Service::Nvnflinger | 35 | } // namespace Service::Nvnflinger |
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp index 687ccc9f9..9e3b68b8a 100644 --- a/src/core/hle/service/nvnflinger/nvnflinger.cpp +++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp | |||
| @@ -1,335 +1,24 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #include <algorithm> | ||
| 5 | #include <optional> | ||
| 6 | |||
| 7 | #include "common/assert.h" | ||
| 8 | #include "common/logging/log.h" | ||
| 9 | #include "common/microprofile.h" | ||
| 10 | #include "common/scope_exit.h" | ||
| 11 | #include "common/settings.h" | ||
| 12 | #include "common/thread.h" | ||
| 13 | #include "core/core.h" | 4 | #include "core/core.h" |
| 14 | #include "core/core_timing.h" | 5 | #include "core/hle/service/nvnflinger/hos_binder_driver.h" |
| 15 | #include "core/hle/kernel/k_readable_event.h" | ||
| 16 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | ||
| 17 | #include "core/hle/service/nvdrv/nvdrv.h" | ||
| 18 | #include "core/hle/service/nvnflinger/buffer_item_consumer.h" | ||
| 19 | #include "core/hle/service/nvnflinger/buffer_queue_core.h" | ||
| 20 | #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" | ||
| 21 | #include "core/hle/service/nvnflinger/hardware_composer.h" | ||
| 22 | #include "core/hle/service/nvnflinger/hos_binder_driver_server.h" | 6 | #include "core/hle/service/nvnflinger/hos_binder_driver_server.h" |
| 23 | #include "core/hle/service/nvnflinger/nvnflinger.h" | 7 | #include "core/hle/service/nvnflinger/nvnflinger.h" |
| 24 | #include "core/hle/service/nvnflinger/ui/graphic_buffer.h" | 8 | #include "core/hle/service/nvnflinger/surface_flinger.h" |
| 25 | #include "core/hle/service/vi/display/vi_display.h" | 9 | #include "core/hle/service/server_manager.h" |
| 26 | #include "core/hle/service/vi/layer/vi_layer.h" | 10 | #include "core/hle/service/sm/sm.h" |
| 27 | #include "core/hle/service/vi/vi_results.h" | ||
| 28 | #include "video_core/gpu.h" | ||
| 29 | #include "video_core/host1x/host1x.h" | ||
| 30 | #include "video_core/host1x/syncpoint_manager.h" | ||
| 31 | 11 | ||
| 32 | namespace Service::Nvnflinger { | 12 | namespace Service::Nvnflinger { |
| 33 | 13 | ||
| 34 | constexpr auto frame_ns = std::chrono::nanoseconds{1000000000 / 60}; | 14 | void LoopProcess(Core::System& system) { |
| 35 | 15 | const auto binder_server = std::make_shared<HosBinderDriverServer>(); | |
| 36 | void Nvnflinger::SplitVSync(std::stop_token stop_token) { | 16 | const auto surface_flinger = std::make_shared<SurfaceFlinger>(system, *binder_server); |
| 37 | system.RegisterHostThread(); | ||
| 38 | std::string name = "VSyncThread"; | ||
| 39 | MicroProfileOnThreadCreate(name.c_str()); | ||
| 40 | |||
| 41 | // Cleanup | ||
| 42 | SCOPE_EXIT({ MicroProfileOnThreadExit(); }); | ||
| 43 | |||
| 44 | Common::SetCurrentThreadName(name.c_str()); | ||
| 45 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); | ||
| 46 | |||
| 47 | while (!stop_token.stop_requested()) { | ||
| 48 | vsync_signal.Wait(); | ||
| 49 | |||
| 50 | const auto lock_guard = Lock(); | ||
| 51 | |||
| 52 | if (!is_abandoned) { | ||
| 53 | Compose(); | ||
| 54 | } | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_) | ||
| 59 | : system(system_), service_context(system_, "nvnflinger"), | ||
| 60 | hos_binder_driver_server(hos_binder_driver_server_) { | ||
| 61 | displays.emplace_back(0, "Default", hos_binder_driver_server, service_context, system); | ||
| 62 | displays.emplace_back(1, "External", hos_binder_driver_server, service_context, system); | ||
| 63 | displays.emplace_back(2, "Edid", hos_binder_driver_server, service_context, system); | ||
| 64 | displays.emplace_back(3, "Internal", hos_binder_driver_server, service_context, system); | ||
| 65 | displays.emplace_back(4, "Null", hos_binder_driver_server, service_context, system); | ||
| 66 | guard = std::make_shared<std::mutex>(); | ||
| 67 | |||
| 68 | // Schedule the screen composition events | ||
| 69 | multi_composition_event = Core::Timing::CreateEvent( | ||
| 70 | "ScreenComposition", | ||
| 71 | [this](s64 time, | ||
| 72 | std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 73 | vsync_signal.Set(); | ||
| 74 | return std::chrono::nanoseconds(GetNextTicks()); | ||
| 75 | }); | ||
| 76 | |||
| 77 | single_composition_event = Core::Timing::CreateEvent( | ||
| 78 | "ScreenComposition", | ||
| 79 | [this](s64 time, | ||
| 80 | std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 81 | const auto lock_guard = Lock(); | ||
| 82 | Compose(); | ||
| 83 | |||
| 84 | return std::chrono::nanoseconds(GetNextTicks()); | ||
| 85 | }); | ||
| 86 | |||
| 87 | if (system.IsMulticore()) { | ||
| 88 | system.CoreTiming().ScheduleLoopingEvent(frame_ns, frame_ns, multi_composition_event); | ||
| 89 | vsync_thread = std::jthread([this](std::stop_token token) { SplitVSync(token); }); | ||
| 90 | } else { | ||
| 91 | system.CoreTiming().ScheduleLoopingEvent(frame_ns, frame_ns, single_composition_event); | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | Nvnflinger::~Nvnflinger() { | ||
| 96 | if (system.IsMulticore()) { | ||
| 97 | system.CoreTiming().UnscheduleEvent(multi_composition_event); | ||
| 98 | vsync_thread.request_stop(); | ||
| 99 | vsync_signal.Set(); | ||
| 100 | } else { | ||
| 101 | system.CoreTiming().UnscheduleEvent(single_composition_event); | ||
| 102 | } | ||
| 103 | |||
| 104 | ShutdownLayers(); | ||
| 105 | |||
| 106 | if (nvdrv) { | ||
| 107 | nvdrv->Close(disp_fd); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | void Nvnflinger::ShutdownLayers() { | ||
| 112 | // Abandon consumers. | ||
| 113 | { | ||
| 114 | const auto lock_guard = Lock(); | ||
| 115 | for (auto& display : displays) { | ||
| 116 | display.Abandon(); | ||
| 117 | } | ||
| 118 | |||
| 119 | is_abandoned = true; | ||
| 120 | } | ||
| 121 | |||
| 122 | // Join the vsync thread, if it exists. | ||
| 123 | vsync_thread = {}; | ||
| 124 | } | ||
| 125 | |||
| 126 | void Nvnflinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { | ||
| 127 | nvdrv = std::move(instance); | ||
| 128 | disp_fd = nvdrv->Open("/dev/nvdisp_disp0", {}); | ||
| 129 | } | ||
| 130 | |||
| 131 | std::optional<u64> Nvnflinger::OpenDisplay(std::string_view name) { | ||
| 132 | const auto lock_guard = Lock(); | ||
| 133 | |||
| 134 | LOG_DEBUG(Service_Nvnflinger, "Opening \"{}\" display", name); | ||
| 135 | |||
| 136 | const auto itr = | ||
| 137 | std::find_if(displays.begin(), displays.end(), | ||
| 138 | [&](const VI::Display& display) { return display.GetName() == name; }); | ||
| 139 | |||
| 140 | if (itr == displays.end()) { | ||
| 141 | return std::nullopt; | ||
| 142 | } | ||
| 143 | |||
| 144 | return itr->GetID(); | ||
| 145 | } | ||
| 146 | |||
| 147 | bool Nvnflinger::CloseDisplay(u64 display_id) { | ||
| 148 | const auto lock_guard = Lock(); | ||
| 149 | auto* const display = FindDisplay(display_id); | ||
| 150 | |||
| 151 | if (display == nullptr) { | ||
| 152 | return false; | ||
| 153 | } | ||
| 154 | |||
| 155 | display->Reset(); | ||
| 156 | |||
| 157 | return true; | ||
| 158 | } | ||
| 159 | |||
| 160 | std::optional<u64> Nvnflinger::CreateLayer(u64 display_id, LayerBlending blending) { | ||
| 161 | const auto lock_guard = Lock(); | ||
| 162 | auto* const display = FindDisplay(display_id); | ||
| 163 | |||
| 164 | if (display == nullptr) { | ||
| 165 | return std::nullopt; | ||
| 166 | } | ||
| 167 | |||
| 168 | const u64 layer_id = next_layer_id++; | ||
| 169 | CreateLayerAtId(*display, layer_id, blending); | ||
| 170 | return layer_id; | ||
| 171 | } | ||
| 172 | |||
| 173 | void Nvnflinger::CreateLayerAtId(VI::Display& display, u64 layer_id, LayerBlending blending) { | ||
| 174 | const auto buffer_id = next_buffer_queue_id++; | ||
| 175 | display.CreateLayer(layer_id, buffer_id, nvdrv->container); | ||
| 176 | display.FindLayer(layer_id)->SetBlending(blending); | ||
| 177 | } | ||
| 178 | |||
| 179 | bool Nvnflinger::OpenLayer(u64 layer_id) { | ||
| 180 | const auto lock_guard = Lock(); | ||
| 181 | |||
| 182 | for (auto& display : displays) { | ||
| 183 | if (auto* layer = display.FindLayer(layer_id); layer) { | ||
| 184 | return layer->Open(); | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | return false; | ||
| 189 | } | ||
| 190 | |||
| 191 | bool Nvnflinger::CloseLayer(u64 layer_id) { | ||
| 192 | const auto lock_guard = Lock(); | ||
| 193 | |||
| 194 | for (auto& display : displays) { | ||
| 195 | if (auto* layer = display.FindLayer(layer_id); layer) { | ||
| 196 | return layer->Close(); | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 200 | return false; | ||
| 201 | } | ||
| 202 | |||
| 203 | void Nvnflinger::SetLayerVisibility(u64 layer_id, bool visible) { | ||
| 204 | const auto lock_guard = Lock(); | ||
| 205 | |||
| 206 | for (auto& display : displays) { | ||
| 207 | if (auto* layer = display.FindLayer(layer_id); layer) { | ||
| 208 | layer->SetVisibility(visible); | ||
| 209 | } | ||
| 210 | } | ||
| 211 | } | ||
| 212 | |||
| 213 | void Nvnflinger::DestroyLayer(u64 layer_id) { | ||
| 214 | const auto lock_guard = Lock(); | ||
| 215 | |||
| 216 | for (auto& display : displays) { | ||
| 217 | display.DestroyLayer(layer_id); | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | std::optional<u32> Nvnflinger::FindBufferQueueId(u64 display_id, u64 layer_id) { | ||
| 222 | const auto lock_guard = Lock(); | ||
| 223 | const auto* const layer = FindLayer(display_id, layer_id); | ||
| 224 | |||
| 225 | if (layer == nullptr) { | ||
| 226 | return std::nullopt; | ||
| 227 | } | ||
| 228 | |||
| 229 | return layer->GetBinderId(); | ||
| 230 | } | ||
| 231 | |||
| 232 | Result Nvnflinger::FindVsyncEvent(Kernel::KReadableEvent** out_vsync_event, u64 display_id) { | ||
| 233 | const auto lock_guard = Lock(); | ||
| 234 | auto* const display = FindDisplay(display_id); | ||
| 235 | |||
| 236 | if (display == nullptr) { | ||
| 237 | return VI::ResultNotFound; | ||
| 238 | } | ||
| 239 | |||
| 240 | *out_vsync_event = display->GetVSyncEvent(); | ||
| 241 | return ResultSuccess; | ||
| 242 | } | ||
| 243 | |||
| 244 | VI::Display* Nvnflinger::FindDisplay(u64 display_id) { | ||
| 245 | const auto itr = | ||
| 246 | std::find_if(displays.begin(), displays.end(), | ||
| 247 | [&](const VI::Display& display) { return display.GetID() == display_id; }); | ||
| 248 | |||
| 249 | if (itr == displays.end()) { | ||
| 250 | return nullptr; | ||
| 251 | } | ||
| 252 | |||
| 253 | return &*itr; | ||
| 254 | } | ||
| 255 | |||
| 256 | const VI::Display* Nvnflinger::FindDisplay(u64 display_id) const { | ||
| 257 | const auto itr = | ||
| 258 | std::find_if(displays.begin(), displays.end(), | ||
| 259 | [&](const VI::Display& display) { return display.GetID() == display_id; }); | ||
| 260 | |||
| 261 | if (itr == displays.end()) { | ||
| 262 | return nullptr; | ||
| 263 | } | ||
| 264 | |||
| 265 | return &*itr; | ||
| 266 | } | ||
| 267 | |||
| 268 | VI::Layer* Nvnflinger::FindLayer(u64 display_id, u64 layer_id) { | ||
| 269 | auto* const display = FindDisplay(display_id); | ||
| 270 | |||
| 271 | if (display == nullptr) { | ||
| 272 | return nullptr; | ||
| 273 | } | ||
| 274 | |||
| 275 | return display->FindLayer(layer_id); | ||
| 276 | } | ||
| 277 | |||
| 278 | void Nvnflinger::Compose() { | ||
| 279 | for (auto& display : displays) { | ||
| 280 | // Trigger vsync for this display at the end of drawing | ||
| 281 | SCOPE_EXIT({ display.SignalVSyncEvent(); }); | ||
| 282 | |||
| 283 | // Don't do anything for displays without layers. | ||
| 284 | if (!display.HasLayers()) { | ||
| 285 | continue; | ||
| 286 | } | ||
| 287 | |||
| 288 | if (!system.IsPoweredOn()) { | ||
| 289 | return; // We are likely shutting down | ||
| 290 | } | ||
| 291 | |||
| 292 | auto nvdisp = nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>(disp_fd); | ||
| 293 | ASSERT(nvdisp); | ||
| 294 | |||
| 295 | swap_interval = display.GetComposer().ComposeLocked(&compose_speed_scale, display, *nvdisp); | ||
| 296 | } | ||
| 297 | } | ||
| 298 | |||
| 299 | s64 Nvnflinger::GetNextTicks() const { | ||
| 300 | const auto& settings = Settings::values; | ||
| 301 | auto speed_scale = 1.f; | ||
| 302 | if (settings.use_multi_core.GetValue()) { | ||
| 303 | if (settings.use_speed_limit.GetValue()) { | ||
| 304 | // Scales the speed based on speed_limit setting on MC. SC is handled by | ||
| 305 | // SpeedLimiter::DoSpeedLimiting. | ||
| 306 | speed_scale = 100.f / settings.speed_limit.GetValue(); | ||
| 307 | } else { | ||
| 308 | // Run at unlocked framerate. | ||
| 309 | speed_scale = 0.01f; | ||
| 310 | } | ||
| 311 | } | ||
| 312 | |||
| 313 | // Adjust by speed limit determined during composition. | ||
| 314 | speed_scale /= compose_speed_scale; | ||
| 315 | |||
| 316 | if (system.GetNVDECActive() && settings.use_video_framerate.GetValue()) { | ||
| 317 | // Run at intended presentation rate during video playback. | ||
| 318 | speed_scale = 1.f; | ||
| 319 | } | ||
| 320 | |||
| 321 | const f32 effective_fps = 60.f / static_cast<f32>(swap_interval); | ||
| 322 | return static_cast<s64>(speed_scale * (1000000000.f / effective_fps)); | ||
| 323 | } | ||
| 324 | |||
| 325 | FbShareBufferManager& Nvnflinger::GetSystemBufferManager() { | ||
| 326 | const auto lock_guard = Lock(); | ||
| 327 | |||
| 328 | if (!system_buffer_manager) { | ||
| 329 | system_buffer_manager = std::make_unique<FbShareBufferManager>(system, *this, nvdrv); | ||
| 330 | } | ||
| 331 | 17 | ||
| 332 | return *system_buffer_manager; | 18 | auto server_manager = std::make_unique<ServerManager>(system); |
| 19 | server_manager->RegisterNamedService( | ||
| 20 | "dispdrv", std::make_shared<IHOSBinderDriver>(system, binder_server, surface_flinger)); | ||
| 21 | ServerManager::RunServer(std::move(server_manager)); | ||
| 333 | } | 22 | } |
| 334 | 23 | ||
| 335 | } // namespace Service::Nvnflinger | 24 | } // namespace Service::Nvnflinger |
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.h b/src/core/hle/service/nvnflinger/nvnflinger.h index 4cf4f069d..5c41f3013 100644 --- a/src/core/hle/service/nvnflinger/nvnflinger.h +++ b/src/core/hle/service/nvnflinger/nvnflinger.h | |||
| @@ -3,170 +3,12 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <list> | 6 | namespace Core { |
| 7 | #include <memory> | 7 | class System; |
| 8 | #include <mutex> | 8 | } |
| 9 | #include <optional> | ||
| 10 | #include <thread> | ||
| 11 | #include <vector> | ||
| 12 | |||
| 13 | #include "common/common_types.h" | ||
| 14 | #include "common/polyfill_thread.h" | ||
| 15 | #include "common/thread.h" | ||
| 16 | #include "core/hle/result.h" | ||
| 17 | #include "core/hle/service/kernel_helpers.h" | ||
| 18 | #include "core/hle/service/nvnflinger/hwc_layer.h" | ||
| 19 | |||
| 20 | namespace Common { | ||
| 21 | class Event; | ||
| 22 | } // namespace Common | ||
| 23 | |||
| 24 | namespace Core::Timing { | ||
| 25 | class CoreTiming; | ||
| 26 | struct EventType; | ||
| 27 | } // namespace Core::Timing | ||
| 28 | |||
| 29 | namespace Kernel { | ||
| 30 | class KReadableEvent; | ||
| 31 | } // namespace Kernel | ||
| 32 | |||
| 33 | namespace Service::Nvidia { | ||
| 34 | class Module; | ||
| 35 | } // namespace Service::Nvidia | ||
| 36 | |||
| 37 | namespace Service::VI { | ||
| 38 | class Display; | ||
| 39 | class Layer; | ||
| 40 | } // namespace Service::VI | ||
| 41 | |||
| 42 | namespace Service::android { | ||
| 43 | class BufferQueueCore; | ||
| 44 | class BufferQueueProducer; | ||
| 45 | } // namespace Service::android | ||
| 46 | 9 | ||
| 47 | namespace Service::Nvnflinger { | 10 | namespace Service::Nvnflinger { |
| 48 | 11 | ||
| 49 | class FbShareBufferManager; | 12 | void LoopProcess(Core::System& system); |
| 50 | class HardwareComposer; | ||
| 51 | class HosBinderDriverServer; | ||
| 52 | |||
| 53 | class Nvnflinger final { | ||
| 54 | public: | ||
| 55 | explicit Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_); | ||
| 56 | ~Nvnflinger(); | ||
| 57 | |||
| 58 | void ShutdownLayers(); | ||
| 59 | |||
| 60 | /// Sets the NVDrv module instance to use to send buffers to the GPU. | ||
| 61 | void SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance); | ||
| 62 | |||
| 63 | /// Opens the specified display and returns the ID. | ||
| 64 | /// | ||
| 65 | /// If an invalid display name is provided, then an empty optional is returned. | ||
| 66 | [[nodiscard]] std::optional<u64> OpenDisplay(std::string_view name); | ||
| 67 | |||
| 68 | /// Closes the specified display by its ID. | ||
| 69 | /// | ||
| 70 | /// Returns false if an invalid display ID is provided. | ||
| 71 | [[nodiscard]] bool CloseDisplay(u64 display_id); | ||
| 72 | |||
| 73 | /// Creates a layer on the specified display and returns the layer ID. | ||
| 74 | /// | ||
| 75 | /// If an invalid display ID is specified, then an empty optional is returned. | ||
| 76 | [[nodiscard]] std::optional<u64> CreateLayer(u64 display_id, | ||
| 77 | LayerBlending blending = LayerBlending::None); | ||
| 78 | |||
| 79 | /// Opens a layer on all displays for the given layer ID. | ||
| 80 | bool OpenLayer(u64 layer_id); | ||
| 81 | |||
| 82 | /// Closes a layer on all displays for the given layer ID. | ||
| 83 | bool CloseLayer(u64 layer_id); | ||
| 84 | |||
| 85 | /// Makes a layer visible on all displays for the given layer ID. | ||
| 86 | void SetLayerVisibility(u64 layer_id, bool visible); | ||
| 87 | |||
| 88 | /// Destroys the given layer ID. | ||
| 89 | void DestroyLayer(u64 layer_id); | ||
| 90 | |||
| 91 | /// Finds the buffer queue ID of the specified layer in the specified display. | ||
| 92 | /// | ||
| 93 | /// If an invalid display ID or layer ID is provided, then an empty optional is returned. | ||
| 94 | [[nodiscard]] std::optional<u32> FindBufferQueueId(u64 display_id, u64 layer_id); | ||
| 95 | |||
| 96 | /// Gets the vsync event for the specified display. | ||
| 97 | /// | ||
| 98 | /// If an invalid display ID is provided, then VI::ResultNotFound is returned. | ||
| 99 | /// If the vsync event has already been retrieved, then VI::ResultPermissionDenied is returned. | ||
| 100 | [[nodiscard]] Result FindVsyncEvent(Kernel::KReadableEvent** out_vsync_event, u64 display_id); | ||
| 101 | |||
| 102 | /// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when | ||
| 103 | /// finished. | ||
| 104 | void Compose(); | ||
| 105 | |||
| 106 | [[nodiscard]] s64 GetNextTicks() const; | ||
| 107 | |||
| 108 | FbShareBufferManager& GetSystemBufferManager(); | ||
| 109 | |||
| 110 | private: | ||
| 111 | struct Layer { | ||
| 112 | std::unique_ptr<android::BufferQueueCore> core; | ||
| 113 | std::unique_ptr<android::BufferQueueProducer> producer; | ||
| 114 | }; | ||
| 115 | |||
| 116 | friend class FbShareBufferManager; | ||
| 117 | |||
| 118 | private: | ||
| 119 | [[nodiscard]] std::unique_lock<std::mutex> Lock() const { | ||
| 120 | return std::unique_lock{*guard}; | ||
| 121 | } | ||
| 122 | |||
| 123 | /// Finds the display identified by the specified ID. | ||
| 124 | [[nodiscard]] VI::Display* FindDisplay(u64 display_id); | ||
| 125 | |||
| 126 | /// Finds the display identified by the specified ID. | ||
| 127 | [[nodiscard]] const VI::Display* FindDisplay(u64 display_id) const; | ||
| 128 | |||
| 129 | /// Finds the layer identified by the specified ID in the desired display. | ||
| 130 | [[nodiscard]] VI::Layer* FindLayer(u64 display_id, u64 layer_id); | ||
| 131 | |||
| 132 | /// Creates a layer with the specified layer ID in the desired display. | ||
| 133 | void CreateLayerAtId(VI::Display& display, u64 layer_id, LayerBlending blending); | ||
| 134 | |||
| 135 | void SplitVSync(std::stop_token stop_token); | ||
| 136 | |||
| 137 | std::shared_ptr<Nvidia::Module> nvdrv; | ||
| 138 | s32 disp_fd; | ||
| 139 | |||
| 140 | std::list<VI::Display> displays; | ||
| 141 | |||
| 142 | /// Id to use for the next layer that is created, this counter is shared among all displays. | ||
| 143 | u64 next_layer_id = 1; | ||
| 144 | /// Id to use for the next buffer queue that is created, this counter is shared among all | ||
| 145 | /// layers. | ||
| 146 | u32 next_buffer_queue_id = 1; | ||
| 147 | |||
| 148 | s32 swap_interval = 1; | ||
| 149 | f32 compose_speed_scale = 1.0f; | ||
| 150 | |||
| 151 | bool is_abandoned = false; | ||
| 152 | |||
| 153 | /// Event that handles screen composition. | ||
| 154 | std::shared_ptr<Core::Timing::EventType> multi_composition_event; | ||
| 155 | std::shared_ptr<Core::Timing::EventType> single_composition_event; | ||
| 156 | |||
| 157 | std::unique_ptr<FbShareBufferManager> system_buffer_manager; | ||
| 158 | |||
| 159 | std::shared_ptr<std::mutex> guard; | ||
| 160 | |||
| 161 | Core::System& system; | ||
| 162 | |||
| 163 | Common::Event vsync_signal; | ||
| 164 | |||
| 165 | std::jthread vsync_thread; | ||
| 166 | |||
| 167 | KernelHelpers::ServiceContext service_context; | ||
| 168 | |||
| 169 | HosBinderDriverServer& hos_binder_driver_server; | ||
| 170 | }; | ||
| 171 | 13 | ||
| 172 | } // namespace Service::Nvnflinger | 14 | } // namespace Service::Nvnflinger |
diff --git a/src/core/hle/service/nvnflinger/surface_flinger.cpp b/src/core/hle/service/nvnflinger/surface_flinger.cpp new file mode 100644 index 000000000..8362b65e5 --- /dev/null +++ b/src/core/hle/service/nvnflinger/surface_flinger.cpp | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/core.h" | ||
| 5 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | ||
| 6 | #include "core/hle/service/nvdrv/nvdrv_interface.h" | ||
| 7 | #include "core/hle/service/nvnflinger/display.h" | ||
| 8 | #include "core/hle/service/nvnflinger/hos_binder_driver_server.h" | ||
| 9 | #include "core/hle/service/nvnflinger/surface_flinger.h" | ||
| 10 | #include "core/hle/service/sm/sm.h" | ||
| 11 | |||
| 12 | #include "core/hle/service/nvnflinger/buffer_queue_consumer.h" | ||
| 13 | #include "core/hle/service/nvnflinger/buffer_queue_core.h" | ||
| 14 | #include "core/hle/service/nvnflinger/buffer_queue_producer.h" | ||
| 15 | |||
| 16 | namespace Service::Nvnflinger { | ||
| 17 | |||
| 18 | SurfaceFlinger::SurfaceFlinger(Core::System& system, HosBinderDriverServer& server) | ||
| 19 | : m_system(system), m_server(server), m_context(m_system, "SurfaceFlinger") { | ||
| 20 | nvdrv = m_system.ServiceManager().GetService<Nvidia::NVDRV>("nvdrv:s", true)->GetModule(); | ||
| 21 | disp_fd = nvdrv->Open("/dev/nvdisp_disp0", {}); | ||
| 22 | } | ||
| 23 | |||
| 24 | SurfaceFlinger::~SurfaceFlinger() { | ||
| 25 | nvdrv->Close(disp_fd); | ||
| 26 | } | ||
| 27 | |||
| 28 | void SurfaceFlinger::AddDisplay(u64 display_id) { | ||
| 29 | m_displays.emplace_back(display_id); | ||
| 30 | } | ||
| 31 | |||
| 32 | void SurfaceFlinger::RemoveDisplay(u64 display_id) { | ||
| 33 | std::erase_if(m_displays, [&](auto& display) { return display.id == display_id; }); | ||
| 34 | } | ||
| 35 | |||
| 36 | bool SurfaceFlinger::ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, | ||
| 37 | u64 display_id) { | ||
| 38 | auto* const display = this->FindDisplay(display_id); | ||
| 39 | if (!display || !display->stack.HasLayers()) { | ||
| 40 | return false; | ||
| 41 | } | ||
| 42 | |||
| 43 | *out_swap_interval = | ||
| 44 | m_composer.ComposeLocked(out_compose_speed_scale, *display, | ||
| 45 | *nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>(disp_fd)); | ||
| 46 | return true; | ||
| 47 | } | ||
| 48 | |||
| 49 | void SurfaceFlinger::CreateLayer(s32 consumer_binder_id) { | ||
| 50 | auto binder = std::static_pointer_cast<android::BufferQueueConsumer>( | ||
| 51 | m_server.TryGetBinder(consumer_binder_id)); | ||
| 52 | if (!binder) { | ||
| 53 | return; | ||
| 54 | } | ||
| 55 | |||
| 56 | auto buffer_item_consumer = std::make_shared<android::BufferItemConsumer>(std::move(binder)); | ||
| 57 | buffer_item_consumer->Connect(false); | ||
| 58 | |||
| 59 | m_layers.layers.emplace_back( | ||
| 60 | std::make_shared<Layer>(std::move(buffer_item_consumer), consumer_binder_id)); | ||
| 61 | } | ||
| 62 | |||
| 63 | void SurfaceFlinger::DestroyLayer(s32 consumer_binder_id) { | ||
| 64 | std::erase_if(m_layers.layers, | ||
| 65 | [&](auto& layer) { return layer->consumer_id == consumer_binder_id; }); | ||
| 66 | } | ||
| 67 | |||
| 68 | void SurfaceFlinger::AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id) { | ||
| 69 | auto* const display = this->FindDisplay(display_id); | ||
| 70 | auto layer = this->FindLayer(consumer_binder_id); | ||
| 71 | |||
| 72 | if (!display || !layer) { | ||
| 73 | return; | ||
| 74 | } | ||
| 75 | |||
| 76 | display->stack.layers.emplace_back(std::move(layer)); | ||
| 77 | } | ||
| 78 | |||
| 79 | void SurfaceFlinger::RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_binder_id) { | ||
| 80 | auto* const display = this->FindDisplay(display_id); | ||
| 81 | if (!display) { | ||
| 82 | return; | ||
| 83 | } | ||
| 84 | |||
| 85 | m_composer.RemoveLayerLocked(*display, consumer_binder_id); | ||
| 86 | std::erase_if(display->stack.layers, | ||
| 87 | [&](auto& layer) { return layer->consumer_id == consumer_binder_id; }); | ||
| 88 | } | ||
| 89 | |||
| 90 | void SurfaceFlinger::SetLayerVisibility(s32 consumer_binder_id, bool visible) { | ||
| 91 | if (const auto layer = this->FindLayer(consumer_binder_id); layer != nullptr) { | ||
| 92 | layer->visible = visible; | ||
| 93 | return; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | void SurfaceFlinger::SetLayerBlending(s32 consumer_binder_id, LayerBlending blending) { | ||
| 98 | if (const auto layer = this->FindLayer(consumer_binder_id); layer != nullptr) { | ||
| 99 | layer->blending = blending; | ||
| 100 | return; | ||
| 101 | } | ||
| 102 | } | ||
| 103 | |||
| 104 | Display* SurfaceFlinger::FindDisplay(u64 display_id) { | ||
| 105 | for (auto& display : m_displays) { | ||
| 106 | if (display.id == display_id) { | ||
| 107 | return &display; | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | return nullptr; | ||
| 112 | } | ||
| 113 | |||
| 114 | std::shared_ptr<Layer> SurfaceFlinger::FindLayer(s32 consumer_binder_id) { | ||
| 115 | for (auto& layer : m_layers.layers) { | ||
| 116 | if (layer->consumer_id == consumer_binder_id) { | ||
| 117 | return layer; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | return nullptr; | ||
| 122 | } | ||
| 123 | |||
| 124 | void SurfaceFlinger::CreateBufferQueue(s32* out_consumer_binder_id, s32* out_producer_binder_id) { | ||
| 125 | auto& nvmap = nvdrv->GetContainer().GetNvMapFile(); | ||
| 126 | auto core = std::make_shared<android::BufferQueueCore>(); | ||
| 127 | auto producer = std::make_shared<android::BufferQueueProducer>(m_context, core, nvmap); | ||
| 128 | auto consumer = std::make_shared<android::BufferQueueConsumer>(core); | ||
| 129 | |||
| 130 | *out_consumer_binder_id = m_server.RegisterBinder(std::move(consumer)); | ||
| 131 | *out_producer_binder_id = m_server.RegisterBinder(std::move(producer)); | ||
| 132 | } | ||
| 133 | |||
| 134 | void SurfaceFlinger::DestroyBufferQueue(s32 consumer_binder_id, s32 producer_binder_id) { | ||
| 135 | m_server.UnregisterBinder(producer_binder_id); | ||
| 136 | m_server.UnregisterBinder(consumer_binder_id); | ||
| 137 | } | ||
| 138 | |||
| 139 | } // namespace Service::Nvnflinger | ||
diff --git a/src/core/hle/service/nvnflinger/surface_flinger.h b/src/core/hle/service/nvnflinger/surface_flinger.h new file mode 100644 index 000000000..406281c83 --- /dev/null +++ b/src/core/hle/service/nvnflinger/surface_flinger.h | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <vector> | ||
| 7 | |||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "core/hle/service/kernel_helpers.h" | ||
| 10 | #include "core/hle/service/nvnflinger/hardware_composer.h" | ||
| 11 | |||
| 12 | namespace Core { | ||
| 13 | class System; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace Service::Nvidia { | ||
| 17 | class Module; | ||
| 18 | } | ||
| 19 | |||
| 20 | // TODO: ISurfaceComposer | ||
| 21 | // TODO: ISurfaceComposerClient | ||
| 22 | |||
| 23 | namespace Service::Nvnflinger { | ||
| 24 | |||
| 25 | struct Display; | ||
| 26 | class HosBinderDriverServer; | ||
| 27 | enum class LayerBlending : u32; | ||
| 28 | struct Layer; | ||
| 29 | |||
| 30 | class SurfaceFlinger { | ||
| 31 | public: | ||
| 32 | explicit SurfaceFlinger(Core::System& system, HosBinderDriverServer& server); | ||
| 33 | ~SurfaceFlinger(); | ||
| 34 | |||
| 35 | void AddDisplay(u64 display_id); | ||
| 36 | void RemoveDisplay(u64 display_id); | ||
| 37 | bool ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id); | ||
| 38 | |||
| 39 | void CreateLayer(s32 consumer_binder_id); | ||
| 40 | void DestroyLayer(s32 consumer_binder_id); | ||
| 41 | |||
| 42 | void AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id); | ||
| 43 | void RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_binder_id); | ||
| 44 | |||
| 45 | void SetLayerVisibility(s32 consumer_binder_id, bool visible); | ||
| 46 | void SetLayerBlending(s32 consumer_binder_id, LayerBlending blending); | ||
| 47 | |||
| 48 | private: | ||
| 49 | Display* FindDisplay(u64 display_id); | ||
| 50 | std::shared_ptr<Layer> FindLayer(s32 consumer_binder_id); | ||
| 51 | |||
| 52 | public: | ||
| 53 | // TODO: these don't belong here | ||
| 54 | void CreateBufferQueue(s32* out_consumer_binder_id, s32* out_producer_binder_id); | ||
| 55 | void DestroyBufferQueue(s32 consumer_binder_id, s32 producer_binder_id); | ||
| 56 | |||
| 57 | private: | ||
| 58 | Core::System& m_system; | ||
| 59 | HosBinderDriverServer& m_server; | ||
| 60 | KernelHelpers::ServiceContext m_context; | ||
| 61 | |||
| 62 | std::vector<Display> m_displays; | ||
| 63 | LayerStack m_layers; | ||
| 64 | std::shared_ptr<Nvidia::Module> nvdrv; | ||
| 65 | s32 disp_fd; | ||
| 66 | HardwareComposer m_composer; | ||
| 67 | }; | ||
| 68 | |||
| 69 | } // namespace Service::Nvnflinger | ||
diff --git a/src/core/hle/service/psc/time/static.cpp b/src/core/hle/service/psc/time/static.cpp index 24b85cc61..9a0adb295 100644 --- a/src/core/hle/service/psc/time/static.cpp +++ b/src/core/hle/service/psc/time/static.cpp | |||
| @@ -144,7 +144,9 @@ Result StaticService::GetStandardSteadyClockRtcValue(Out<s64> out_rtc_value) { | |||
| 144 | 144 | ||
| 145 | Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled( | 145 | Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled( |
| 146 | Out<bool> out_is_enabled) { | 146 | Out<bool> out_is_enabled) { |
| 147 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_enabled={}", *out_is_enabled); }); | 147 | SCOPE_EXIT { |
| 148 | LOG_DEBUG(Service_Time, "called. out_is_enabled={}", *out_is_enabled); | ||
| 149 | }; | ||
| 148 | 150 | ||
| 149 | R_UNLESS(m_user_system_clock.IsInitialized(), ResultClockUninitialized); | 151 | R_UNLESS(m_user_system_clock.IsInitialized(), ResultClockUninitialized); |
| 150 | 152 | ||
| @@ -180,7 +182,9 @@ Result StaticService::GetStandardUserSystemClockInitialYear(Out<s32> out_year) { | |||
| 180 | } | 182 | } |
| 181 | 183 | ||
| 182 | Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(Out<bool> out_is_sufficient) { | 184 | Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(Out<bool> out_is_sufficient) { |
| 183 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_sufficient={}", *out_is_sufficient); }); | 185 | SCOPE_EXIT { |
| 186 | LOG_DEBUG(Service_Time, "called. out_is_sufficient={}", *out_is_sufficient); | ||
| 187 | }; | ||
| 184 | 188 | ||
| 185 | *out_is_sufficient = m_network_system_clock.IsAccuracySufficient(); | 189 | *out_is_sufficient = m_network_system_clock.IsAccuracySufficient(); |
| 186 | 190 | ||
| @@ -189,7 +193,9 @@ Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(Out<bool> o | |||
| 189 | 193 | ||
| 190 | Result StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( | 194 | Result StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( |
| 191 | Out<SteadyClockTimePoint> out_time_point) { | 195 | Out<SteadyClockTimePoint> out_time_point) { |
| 192 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); }); | 196 | SCOPE_EXIT { |
| 197 | LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); | ||
| 198 | }; | ||
| 193 | 199 | ||
| 194 | R_UNLESS(m_user_system_clock.IsInitialized(), ResultClockUninitialized); | 200 | R_UNLESS(m_user_system_clock.IsInitialized(), ResultClockUninitialized); |
| 195 | 201 | ||
| @@ -200,7 +206,9 @@ Result StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( | |||
| 200 | 206 | ||
| 201 | Result StaticService::CalculateMonotonicSystemClockBaseTimePoint( | 207 | Result StaticService::CalculateMonotonicSystemClockBaseTimePoint( |
| 202 | Out<s64> out_time, const SystemClockContext& context) { | 208 | Out<s64> out_time, const SystemClockContext& context) { |
| 203 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. context={} out_time={}", context, *out_time); }); | 209 | SCOPE_EXIT { |
| 210 | LOG_DEBUG(Service_Time, "called. context={} out_time={}", context, *out_time); | ||
| 211 | }; | ||
| 204 | 212 | ||
| 205 | R_UNLESS(m_time->m_standard_steady_clock.IsInitialized(), ResultClockUninitialized); | 213 | R_UNLESS(m_time->m_standard_steady_clock.IsInitialized(), ResultClockUninitialized); |
| 206 | 214 | ||
| @@ -219,8 +227,9 @@ Result StaticService::CalculateMonotonicSystemClockBaseTimePoint( | |||
| 219 | } | 227 | } |
| 220 | 228 | ||
| 221 | Result StaticService::GetClockSnapshot(OutClockSnapshot out_snapshot, TimeType type) { | 229 | Result StaticService::GetClockSnapshot(OutClockSnapshot out_snapshot, TimeType type) { |
| 222 | SCOPE_EXIT( | 230 | SCOPE_EXIT { |
| 223 | { LOG_DEBUG(Service_Time, "called. type={} out_snapshot={}", type, *out_snapshot); }); | 231 | LOG_DEBUG(Service_Time, "called. type={} out_snapshot={}", type, *out_snapshot); |
| 232 | }; | ||
| 224 | 233 | ||
| 225 | SystemClockContext user_context{}; | 234 | SystemClockContext user_context{}; |
| 226 | R_TRY(m_user_system_clock.GetContext(user_context)); | 235 | R_TRY(m_user_system_clock.GetContext(user_context)); |
| @@ -234,11 +243,11 @@ Result StaticService::GetClockSnapshot(OutClockSnapshot out_snapshot, TimeType t | |||
| 234 | Result StaticService::GetClockSnapshotFromSystemClockContext( | 243 | Result StaticService::GetClockSnapshotFromSystemClockContext( |
| 235 | TimeType type, OutClockSnapshot out_snapshot, const SystemClockContext& user_context, | 244 | TimeType type, OutClockSnapshot out_snapshot, const SystemClockContext& user_context, |
| 236 | const SystemClockContext& network_context) { | 245 | const SystemClockContext& network_context) { |
| 237 | SCOPE_EXIT({ | 246 | SCOPE_EXIT { |
| 238 | LOG_DEBUG(Service_Time, | 247 | LOG_DEBUG(Service_Time, |
| 239 | "called. type={} user_context={} network_context={} out_snapshot={}", type, | 248 | "called. type={} user_context={} network_context={} out_snapshot={}", type, |
| 240 | user_context, network_context, *out_snapshot); | 249 | user_context, network_context, *out_snapshot); |
| 241 | }); | 250 | }; |
| 242 | 251 | ||
| 243 | R_RETURN(GetClockSnapshotImpl(out_snapshot, user_context, network_context, type)); | 252 | R_RETURN(GetClockSnapshotImpl(out_snapshot, user_context, network_context, type)); |
| 244 | } | 253 | } |
| @@ -246,9 +255,9 @@ Result StaticService::GetClockSnapshotFromSystemClockContext( | |||
| 246 | Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(Out<s64> out_difference, | 255 | Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(Out<s64> out_difference, |
| 247 | InClockSnapshot a, | 256 | InClockSnapshot a, |
| 248 | InClockSnapshot b) { | 257 | InClockSnapshot b) { |
| 249 | SCOPE_EXIT({ | 258 | SCOPE_EXIT { |
| 250 | LOG_DEBUG(Service_Time, "called. a={} b={} out_difference={}", *a, *b, *out_difference); | 259 | LOG_DEBUG(Service_Time, "called. a={} b={} out_difference={}", *a, *b, *out_difference); |
| 251 | }); | 260 | }; |
| 252 | 261 | ||
| 253 | auto diff_s = | 262 | auto diff_s = |
| 254 | std::chrono::seconds(b->user_context.offset) - std::chrono::seconds(a->user_context.offset); | 263 | std::chrono::seconds(b->user_context.offset) - std::chrono::seconds(a->user_context.offset); |
| @@ -276,7 +285,9 @@ Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(Out<s64> | |||
| 276 | 285 | ||
| 277 | Result StaticService::CalculateSpanBetween(Out<s64> out_time, InClockSnapshot a, | 286 | Result StaticService::CalculateSpanBetween(Out<s64> out_time, InClockSnapshot a, |
| 278 | InClockSnapshot b) { | 287 | InClockSnapshot b) { |
| 279 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); }); | 288 | SCOPE_EXIT { |
| 289 | LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); | ||
| 290 | }; | ||
| 280 | 291 | ||
| 281 | s64 time_s{}; | 292 | s64 time_s{}; |
| 282 | auto res = | 293 | auto res = |
diff --git a/src/core/hle/service/psc/time/steady_clock.cpp b/src/core/hle/service/psc/time/steady_clock.cpp index 948610a2b..78dcf532c 100644 --- a/src/core/hle/service/psc/time/steady_clock.cpp +++ b/src/core/hle/service/psc/time/steady_clock.cpp | |||
| @@ -29,7 +29,9 @@ SteadyClock::SteadyClock(Core::System& system_, std::shared_ptr<TimeManager> man | |||
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | Result SteadyClock::GetCurrentTimePoint(Out<SteadyClockTimePoint> out_time_point) { | 31 | Result SteadyClock::GetCurrentTimePoint(Out<SteadyClockTimePoint> out_time_point) { |
| 32 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); }); | 32 | SCOPE_EXIT { |
| 33 | LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); | ||
| 34 | }; | ||
| 33 | 35 | ||
| 34 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), | 36 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), |
| 35 | ResultClockUninitialized); | 37 | ResultClockUninitialized); |
| @@ -38,7 +40,9 @@ Result SteadyClock::GetCurrentTimePoint(Out<SteadyClockTimePoint> out_time_point | |||
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | Result SteadyClock::GetTestOffset(Out<s64> out_test_offset) { | 42 | Result SteadyClock::GetTestOffset(Out<s64> out_test_offset) { |
| 41 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_test_offset={}", *out_test_offset); }); | 43 | SCOPE_EXIT { |
| 44 | LOG_DEBUG(Service_Time, "called. out_test_offset={}", *out_test_offset); | ||
| 45 | }; | ||
| 42 | 46 | ||
| 43 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), | 47 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), |
| 44 | ResultClockUninitialized); | 48 | ResultClockUninitialized); |
| @@ -59,7 +63,9 @@ Result SteadyClock::SetTestOffset(s64 test_offset) { | |||
| 59 | } | 63 | } |
| 60 | 64 | ||
| 61 | Result SteadyClock::GetRtcValue(Out<s64> out_rtc_value) { | 65 | Result SteadyClock::GetRtcValue(Out<s64> out_rtc_value) { |
| 62 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rtc_value={}", *out_rtc_value); }); | 66 | SCOPE_EXIT { |
| 67 | LOG_DEBUG(Service_Time, "called. out_rtc_value={}", *out_rtc_value); | ||
| 68 | }; | ||
| 63 | 69 | ||
| 64 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), | 70 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), |
| 65 | ResultClockUninitialized); | 71 | ResultClockUninitialized); |
| @@ -68,7 +74,9 @@ Result SteadyClock::GetRtcValue(Out<s64> out_rtc_value) { | |||
| 68 | } | 74 | } |
| 69 | 75 | ||
| 70 | Result SteadyClock::IsRtcResetDetected(Out<bool> out_is_detected) { | 76 | Result SteadyClock::IsRtcResetDetected(Out<bool> out_is_detected) { |
| 71 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_detected={}", *out_is_detected); }); | 77 | SCOPE_EXIT { |
| 78 | LOG_DEBUG(Service_Time, "called. out_is_detected={}", *out_is_detected); | ||
| 79 | }; | ||
| 72 | 80 | ||
| 73 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), | 81 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), |
| 74 | ResultClockUninitialized); | 82 | ResultClockUninitialized); |
| @@ -78,7 +86,9 @@ Result SteadyClock::IsRtcResetDetected(Out<bool> out_is_detected) { | |||
| 78 | } | 86 | } |
| 79 | 87 | ||
| 80 | Result SteadyClock::GetSetupResultValue(Out<Result> out_result) { | 88 | Result SteadyClock::GetSetupResultValue(Out<Result> out_result) { |
| 81 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_result=0x{:X}", out_result->raw); }); | 89 | SCOPE_EXIT { |
| 90 | LOG_DEBUG(Service_Time, "called. out_result=0x{:X}", out_result->raw); | ||
| 91 | }; | ||
| 82 | 92 | ||
| 83 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), | 93 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), |
| 84 | ResultClockUninitialized); | 94 | ResultClockUninitialized); |
| @@ -88,8 +98,9 @@ Result SteadyClock::GetSetupResultValue(Out<Result> out_result) { | |||
| 88 | } | 98 | } |
| 89 | 99 | ||
| 90 | Result SteadyClock::GetInternalOffset(Out<s64> out_internal_offset) { | 100 | Result SteadyClock::GetInternalOffset(Out<s64> out_internal_offset) { |
| 91 | SCOPE_EXIT( | 101 | SCOPE_EXIT { |
| 92 | { LOG_DEBUG(Service_Time, "called. out_internal_offset={}", *out_internal_offset); }); | 102 | LOG_DEBUG(Service_Time, "called. out_internal_offset={}", *out_internal_offset); |
| 103 | }; | ||
| 93 | 104 | ||
| 94 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), | 105 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), |
| 95 | ResultClockUninitialized); | 106 | ResultClockUninitialized); |
diff --git a/src/core/hle/service/psc/time/system_clock.cpp b/src/core/hle/service/psc/time/system_clock.cpp index b4e9264d8..9f841d8e0 100644 --- a/src/core/hle/service/psc/time/system_clock.cpp +++ b/src/core/hle/service/psc/time/system_clock.cpp | |||
| @@ -26,7 +26,9 @@ SystemClock::SystemClock(Core::System& system_, SystemClockCore& clock_core, boo | |||
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | Result SystemClock::GetCurrentTime(Out<s64> out_time) { | 28 | Result SystemClock::GetCurrentTime(Out<s64> out_time) { |
| 29 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time={}", *out_time); }); | 29 | SCOPE_EXIT { |
| 30 | LOG_DEBUG(Service_Time, "called. out_time={}", *out_time); | ||
| 31 | }; | ||
| 30 | 32 | ||
| 31 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), | 33 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), |
| 32 | ResultClockUninitialized); | 34 | ResultClockUninitialized); |
| @@ -45,7 +47,9 @@ Result SystemClock::SetCurrentTime(s64 time) { | |||
| 45 | } | 47 | } |
| 46 | 48 | ||
| 47 | Result SystemClock::GetSystemClockContext(Out<SystemClockContext> out_context) { | 49 | Result SystemClock::GetSystemClockContext(Out<SystemClockContext> out_context) { |
| 48 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_context={}", *out_context); }); | 50 | SCOPE_EXIT { |
| 51 | LOG_DEBUG(Service_Time, "called. out_context={}", *out_context); | ||
| 52 | }; | ||
| 49 | 53 | ||
| 50 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), | 54 | R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), |
| 51 | ResultClockUninitialized); | 55 | ResultClockUninitialized); |
diff --git a/src/core/hle/service/psc/time/time_zone_service.cpp b/src/core/hle/service/psc/time/time_zone_service.cpp index 2f80030a4..9e0674f27 100644 --- a/src/core/hle/service/psc/time/time_zone_service.cpp +++ b/src/core/hle/service/psc/time/time_zone_service.cpp | |||
| @@ -37,7 +37,9 @@ TimeZoneService::TimeZoneService(Core::System& system_, StandardSteadyClockCore& | |||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | Result TimeZoneService::GetDeviceLocationName(Out<LocationName> out_location_name) { | 39 | Result TimeZoneService::GetDeviceLocationName(Out<LocationName> out_location_name) { |
| 40 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_location_name={}", *out_location_name); }); | 40 | SCOPE_EXIT { |
| 41 | LOG_DEBUG(Service_Time, "called. out_location_name={}", *out_location_name); | ||
| 42 | }; | ||
| 41 | 43 | ||
| 42 | R_RETURN(m_time_zone.GetLocationName(*out_location_name)); | 44 | R_RETURN(m_time_zone.GetLocationName(*out_location_name)); |
| 43 | } | 45 | } |
| @@ -50,7 +52,9 @@ Result TimeZoneService::SetDeviceLocationName(const LocationName& location_name) | |||
| 50 | } | 52 | } |
| 51 | 53 | ||
| 52 | Result TimeZoneService::GetTotalLocationNameCount(Out<u32> out_count) { | 54 | Result TimeZoneService::GetTotalLocationNameCount(Out<u32> out_count) { |
| 53 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_count={}", *out_count); }); | 55 | SCOPE_EXIT { |
| 56 | LOG_DEBUG(Service_Time, "called. out_count={}", *out_count); | ||
| 57 | }; | ||
| 54 | 58 | ||
| 55 | R_RETURN(m_time_zone.GetTotalLocationCount(*out_count)); | 59 | R_RETURN(m_time_zone.GetTotalLocationCount(*out_count)); |
| 56 | } | 60 | } |
| @@ -69,17 +73,19 @@ Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule, const LocationName& l | |||
| 69 | } | 73 | } |
| 70 | 74 | ||
| 71 | Result TimeZoneService::GetTimeZoneRuleVersion(Out<RuleVersion> out_rule_version) { | 75 | Result TimeZoneService::GetTimeZoneRuleVersion(Out<RuleVersion> out_rule_version) { |
| 72 | SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rule_version={}", *out_rule_version); }); | 76 | SCOPE_EXIT { |
| 77 | LOG_DEBUG(Service_Time, "called. out_rule_version={}", *out_rule_version); | ||
| 78 | }; | ||
| 73 | 79 | ||
| 74 | R_RETURN(m_time_zone.GetRuleVersion(*out_rule_version)); | 80 | R_RETURN(m_time_zone.GetRuleVersion(*out_rule_version)); |
| 75 | } | 81 | } |
| 76 | 82 | ||
| 77 | Result TimeZoneService::GetDeviceLocationNameAndUpdatedTime( | 83 | Result TimeZoneService::GetDeviceLocationNameAndUpdatedTime( |
| 78 | Out<LocationName> out_location_name, Out<SteadyClockTimePoint> out_time_point) { | 84 | Out<LocationName> out_location_name, Out<SteadyClockTimePoint> out_time_point) { |
| 79 | SCOPE_EXIT({ | 85 | SCOPE_EXIT { |
| 80 | LOG_DEBUG(Service_Time, "called. out_location_name={} out_time_point={}", | 86 | LOG_DEBUG(Service_Time, "called. out_location_name={} out_time_point={}", |
| 81 | *out_location_name, *out_time_point); | 87 | *out_location_name, *out_time_point); |
| 82 | }); | 88 | }; |
| 83 | 89 | ||
| 84 | R_TRY(m_time_zone.GetLocationName(*out_location_name)); | 90 | R_TRY(m_time_zone.GetLocationName(*out_location_name)); |
| 85 | R_RETURN(m_time_zone.GetTimePoint(*out_time_point)); | 91 | R_RETURN(m_time_zone.GetTimePoint(*out_time_point)); |
| @@ -116,10 +122,10 @@ Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle( | |||
| 116 | Result TimeZoneService::ToCalendarTime(Out<CalendarTime> out_calendar_time, | 122 | Result TimeZoneService::ToCalendarTime(Out<CalendarTime> out_calendar_time, |
| 117 | Out<CalendarAdditionalInfo> out_additional_info, s64 time, | 123 | Out<CalendarAdditionalInfo> out_additional_info, s64 time, |
| 118 | InRule rule) { | 124 | InRule rule) { |
| 119 | SCOPE_EXIT({ | 125 | SCOPE_EXIT { |
| 120 | LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, | 126 | LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, |
| 121 | *out_calendar_time, *out_additional_info); | 127 | *out_calendar_time, *out_additional_info); |
| 122 | }); | 128 | }; |
| 123 | 129 | ||
| 124 | R_RETURN( | 130 | R_RETURN( |
| 125 | m_time_zone.ToCalendarTime(*out_calendar_time, *out_additional_info, time, *rule.Get())); | 131 | m_time_zone.ToCalendarTime(*out_calendar_time, *out_additional_info, time, *rule.Get())); |
| @@ -128,10 +134,10 @@ Result TimeZoneService::ToCalendarTime(Out<CalendarTime> out_calendar_time, | |||
| 128 | Result TimeZoneService::ToCalendarTimeWithMyRule(Out<CalendarTime> out_calendar_time, | 134 | Result TimeZoneService::ToCalendarTimeWithMyRule(Out<CalendarTime> out_calendar_time, |
| 129 | Out<CalendarAdditionalInfo> out_additional_info, | 135 | Out<CalendarAdditionalInfo> out_additional_info, |
| 130 | s64 time) { | 136 | s64 time) { |
| 131 | SCOPE_EXIT({ | 137 | SCOPE_EXIT { |
| 132 | LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, | 138 | LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, |
| 133 | *out_calendar_time, *out_additional_info); | 139 | *out_calendar_time, *out_additional_info); |
| 134 | }); | 140 | }; |
| 135 | 141 | ||
| 136 | R_RETURN(m_time_zone.ToCalendarTimeWithMyRule(*out_calendar_time, *out_additional_info, time)); | 142 | R_RETURN(m_time_zone.ToCalendarTimeWithMyRule(*out_calendar_time, *out_additional_info, time)); |
| 137 | } | 143 | } |
| @@ -139,11 +145,11 @@ Result TimeZoneService::ToCalendarTimeWithMyRule(Out<CalendarTime> out_calendar_ | |||
| 139 | Result TimeZoneService::ToPosixTime(Out<u32> out_count, | 145 | Result TimeZoneService::ToPosixTime(Out<u32> out_count, |
| 140 | OutArray<s64, BufferAttr_HipcPointer> out_times, | 146 | OutArray<s64, BufferAttr_HipcPointer> out_times, |
| 141 | const CalendarTime& calendar_time, InRule rule) { | 147 | const CalendarTime& calendar_time, InRule rule) { |
| 142 | SCOPE_EXIT({ | 148 | SCOPE_EXIT { |
| 143 | LOG_DEBUG(Service_Time, | 149 | LOG_DEBUG(Service_Time, |
| 144 | "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} ", | 150 | "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} ", |
| 145 | calendar_time, *out_count, out_times[0], out_times[1]); | 151 | calendar_time, *out_count, out_times[0], out_times[1]); |
| 146 | }); | 152 | }; |
| 147 | 153 | ||
| 148 | R_RETURN( | 154 | R_RETURN( |
| 149 | m_time_zone.ToPosixTime(*out_count, out_times, out_times.size(), calendar_time, *rule)); | 155 | m_time_zone.ToPosixTime(*out_count, out_times, out_times.size(), calendar_time, *rule)); |
| @@ -152,11 +158,11 @@ Result TimeZoneService::ToPosixTime(Out<u32> out_count, | |||
| 152 | Result TimeZoneService::ToPosixTimeWithMyRule(Out<u32> out_count, | 158 | Result TimeZoneService::ToPosixTimeWithMyRule(Out<u32> out_count, |
| 153 | OutArray<s64, BufferAttr_HipcPointer> out_times, | 159 | OutArray<s64, BufferAttr_HipcPointer> out_times, |
| 154 | const CalendarTime& calendar_time) { | 160 | const CalendarTime& calendar_time) { |
| 155 | SCOPE_EXIT({ | 161 | SCOPE_EXIT { |
| 156 | LOG_DEBUG(Service_Time, | 162 | LOG_DEBUG(Service_Time, |
| 157 | "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} ", | 163 | "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} ", |
| 158 | calendar_time, *out_count, out_times[0], out_times[1]); | 164 | calendar_time, *out_count, out_times[0], out_times[1]); |
| 159 | }); | 165 | }; |
| 160 | 166 | ||
| 161 | R_RETURN( | 167 | R_RETURN( |
| 162 | m_time_zone.ToPosixTimeWithMyRule(*out_count, out_times, out_times.size(), calendar_time)); | 168 | m_time_zone.ToPosixTimeWithMyRule(*out_count, out_times, out_times.size(), calendar_time)); |
diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp index 8c7f94c8c..0b41bbcb9 100644 --- a/src/core/hle/service/server_manager.cpp +++ b/src/core/hle/service/server_manager.cpp | |||
| @@ -177,10 +177,10 @@ Result ServerManager::ManageNamedPort(const std::string& service_name, | |||
| 177 | Kernel::KPort::Register(m_system.Kernel(), port); | 177 | Kernel::KPort::Register(m_system.Kernel(), port); |
| 178 | 178 | ||
| 179 | // Ensure that our reference to the port is closed if we fail to register it. | 179 | // Ensure that our reference to the port is closed if we fail to register it. |
| 180 | SCOPE_EXIT({ | 180 | SCOPE_EXIT { |
| 181 | port->GetClientPort().Close(); | 181 | port->GetClientPort().Close(); |
| 182 | port->GetServerPort().Close(); | 182 | port->GetServerPort().Close(); |
| 183 | }); | 183 | }; |
| 184 | 184 | ||
| 185 | // Register the object name with the kernel. | 185 | // Register the object name with the kernel. |
| 186 | R_TRY(Kernel::KObjectName::NewFromName(m_system.Kernel(), std::addressof(port->GetClientPort()), | 186 | R_TRY(Kernel::KObjectName::NewFromName(m_system.Kernel(), std::addressof(port->GetClientPort()), |
| @@ -237,7 +237,9 @@ void ServerManager::StartAdditionalHostThreads(const char* name, size_t num_thre | |||
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | Result ServerManager::LoopProcess() { | 239 | Result ServerManager::LoopProcess() { |
| 240 | SCOPE_EXIT({ m_stopped.Set(); }); | 240 | SCOPE_EXIT { |
| 241 | m_stopped.Set(); | ||
| 242 | }; | ||
| 241 | 243 | ||
| 242 | R_RETURN(this->LoopProcessImpl()); | 244 | R_RETURN(this->LoopProcessImpl()); |
| 243 | } | 245 | } |
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index fbdf217ba..ce5e3b5b4 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -7,68 +7,10 @@ | |||
| 7 | #include "common/settings.h" | 7 | #include "common/settings.h" |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/ipc.h" | 9 | #include "core/hle/ipc.h" |
| 10 | #include "core/hle/kernel/k_process.h" | ||
| 11 | #include "core/hle/kernel/k_server_port.h" | ||
| 12 | #include "core/hle/kernel/kernel.h" | 10 | #include "core/hle/kernel/kernel.h" |
| 13 | #include "core/hle/service/acc/acc.h" | ||
| 14 | #include "core/hle/service/am/am.h" | ||
| 15 | #include "core/hle/service/aoc/aoc_u.h" | ||
| 16 | #include "core/hle/service/apm/apm.h" | ||
| 17 | #include "core/hle/service/audio/audio.h" | ||
| 18 | #include "core/hle/service/bcat/bcat.h" | ||
| 19 | #include "core/hle/service/bpc/bpc.h" | ||
| 20 | #include "core/hle/service/btdrv/btdrv.h" | ||
| 21 | #include "core/hle/service/btm/btm.h" | ||
| 22 | #include "core/hle/service/caps/caps.h" | ||
| 23 | #include "core/hle/service/erpt/erpt.h" | ||
| 24 | #include "core/hle/service/es/es.h" | ||
| 25 | #include "core/hle/service/eupld/eupld.h" | ||
| 26 | #include "core/hle/service/fatal/fatal.h" | ||
| 27 | #include "core/hle/service/fgm/fgm.h" | ||
| 28 | #include "core/hle/service/filesystem/filesystem.h" | ||
| 29 | #include "core/hle/service/friend/friend.h" | ||
| 30 | #include "core/hle/service/glue/glue.h" | ||
| 31 | #include "core/hle/service/grc/grc.h" | ||
| 32 | #include "core/hle/service/hid/hid.h" | ||
| 33 | #include "core/hle/service/ipc_helpers.h" | 11 | #include "core/hle/service/ipc_helpers.h" |
| 34 | #include "core/hle/service/jit/jit.h" | ||
| 35 | #include "core/hle/service/lbl/lbl.h" | ||
| 36 | #include "core/hle/service/ldn/ldn.h" | ||
| 37 | #include "core/hle/service/ldr/ldr.h" | ||
| 38 | #include "core/hle/service/lm/lm.h" | ||
| 39 | #include "core/hle/service/mig/mig.h" | ||
| 40 | #include "core/hle/service/mii/mii.h" | ||
| 41 | #include "core/hle/service/mm/mm_u.h" | ||
| 42 | #include "core/hle/service/mnpp/mnpp_app.h" | ||
| 43 | #include "core/hle/service/ncm/ncm.h" | ||
| 44 | #include "core/hle/service/nfc/nfc.h" | ||
| 45 | #include "core/hle/service/nfp/nfp.h" | ||
| 46 | #include "core/hle/service/ngc/ngc.h" | ||
| 47 | #include "core/hle/service/nifm/nifm.h" | ||
| 48 | #include "core/hle/service/nim/nim.h" | ||
| 49 | #include "core/hle/service/npns/npns.h" | ||
| 50 | #include "core/hle/service/ns/ns.h" | ||
| 51 | #include "core/hle/service/nvdrv/nvdrv.h" | ||
| 52 | #include "core/hle/service/nvnflinger/hos_binder_driver_server.h" | ||
| 53 | #include "core/hle/service/nvnflinger/nvnflinger.h" | ||
| 54 | #include "core/hle/service/olsc/olsc.h" | ||
| 55 | #include "core/hle/service/omm/omm.h" | ||
| 56 | #include "core/hle/service/pcie/pcie.h" | ||
| 57 | #include "core/hle/service/pctl/pctl_module.h" | ||
| 58 | #include "core/hle/service/pcv/pcv.h" | ||
| 59 | #include "core/hle/service/pm/pm.h" | ||
| 60 | #include "core/hle/service/prepo/prepo.h" | ||
| 61 | #include "core/hle/service/psc/psc.h" | ||
| 62 | #include "core/hle/service/ptm/ptm.h" | ||
| 63 | #include "core/hle/service/ro/ro.h" | ||
| 64 | #include "core/hle/service/service.h" | 12 | #include "core/hle/service/service.h" |
| 65 | #include "core/hle/service/set/settings.h" | ||
| 66 | #include "core/hle/service/sm/sm.h" | 13 | #include "core/hle/service/sm/sm.h" |
| 67 | #include "core/hle/service/sockets/sockets.h" | ||
| 68 | #include "core/hle/service/spl/spl_module.h" | ||
| 69 | #include "core/hle/service/ssl/ssl.h" | ||
| 70 | #include "core/hle/service/usb/usb.h" | ||
| 71 | #include "core/hle/service/vi/vi.h" | ||
| 72 | #include "core/reporter.h" | 14 | #include "core/reporter.h" |
| 73 | 15 | ||
| 74 | namespace Service { | 16 | namespace Service { |
| @@ -209,82 +151,4 @@ Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session, | |||
| 209 | return result; | 151 | return result; |
| 210 | } | 152 | } |
| 211 | 153 | ||
| 212 | /// Initialize Services | ||
| 213 | Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) | ||
| 214 | : hos_binder_driver_server{std::make_unique<Nvnflinger::HosBinderDriverServer>(system)}, | ||
| 215 | nv_flinger{std::make_unique<Nvnflinger::Nvnflinger>(system, *hos_binder_driver_server)} { | ||
| 216 | |||
| 217 | auto& kernel = system.Kernel(); | ||
| 218 | |||
| 219 | // Nvnflinger needs to be accessed by several services like Vi and AppletOE so we instantiate it | ||
| 220 | // here and pass it into the respective InstallInterfaces functions. | ||
| 221 | system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false); | ||
| 222 | |||
| 223 | // clang-format off | ||
| 224 | kernel.RunOnHostCoreProcess("audio", [&] { Audio::LoopProcess(system); }).detach(); | ||
| 225 | kernel.RunOnHostCoreProcess("FS", [&] { FileSystem::LoopProcess(system); }).detach(); | ||
| 226 | kernel.RunOnHostCoreProcess("jit", [&] { JIT::LoopProcess(system); }).detach(); | ||
| 227 | kernel.RunOnHostCoreProcess("ldn", [&] { LDN::LoopProcess(system); }).detach(); | ||
| 228 | kernel.RunOnHostCoreProcess("Loader", [&] { LDR::LoopProcess(system); }).detach(); | ||
| 229 | kernel.RunOnHostCoreProcess("nvservices", [&] { Nvidia::LoopProcess(*nv_flinger, system); }).detach(); | ||
| 230 | kernel.RunOnHostCoreProcess("bsdsocket", [&] { Sockets::LoopProcess(system); }).detach(); | ||
| 231 | kernel.RunOnHostCoreProcess("vi", [&] { VI::LoopProcess(system, *nv_flinger, *hos_binder_driver_server); }).detach(); | ||
| 232 | |||
| 233 | kernel.RunOnGuestCoreProcess("sm", [&] { SM::LoopProcess(system); }); | ||
| 234 | kernel.RunOnGuestCoreProcess("account", [&] { Account::LoopProcess(system); }); | ||
| 235 | kernel.RunOnGuestCoreProcess("am", [&] { AM::LoopProcess(*nv_flinger, system); }); | ||
| 236 | kernel.RunOnGuestCoreProcess("aoc", [&] { AOC::LoopProcess(system); }); | ||
| 237 | kernel.RunOnGuestCoreProcess("apm", [&] { APM::LoopProcess(system); }); | ||
| 238 | kernel.RunOnGuestCoreProcess("bcat", [&] { BCAT::LoopProcess(system); }); | ||
| 239 | kernel.RunOnGuestCoreProcess("bpc", [&] { BPC::LoopProcess(system); }); | ||
| 240 | kernel.RunOnGuestCoreProcess("btdrv", [&] { BtDrv::LoopProcess(system); }); | ||
| 241 | kernel.RunOnGuestCoreProcess("btm", [&] { BTM::LoopProcess(system); }); | ||
| 242 | kernel.RunOnGuestCoreProcess("capsrv", [&] { Capture::LoopProcess(system); }); | ||
| 243 | kernel.RunOnGuestCoreProcess("erpt", [&] { ERPT::LoopProcess(system); }); | ||
| 244 | kernel.RunOnGuestCoreProcess("es", [&] { ES::LoopProcess(system); }); | ||
| 245 | kernel.RunOnGuestCoreProcess("eupld", [&] { EUPLD::LoopProcess(system); }); | ||
| 246 | kernel.RunOnGuestCoreProcess("fatal", [&] { Fatal::LoopProcess(system); }); | ||
| 247 | kernel.RunOnGuestCoreProcess("fgm", [&] { FGM::LoopProcess(system); }); | ||
| 248 | kernel.RunOnGuestCoreProcess("friends", [&] { Friend::LoopProcess(system); }); | ||
| 249 | // glue depends on settings and psc, so they must come first | ||
| 250 | kernel.RunOnGuestCoreProcess("settings", [&] { Set::LoopProcess(system); }); | ||
| 251 | kernel.RunOnGuestCoreProcess("psc", [&] { PSC::LoopProcess(system); }); | ||
| 252 | kernel.RunOnGuestCoreProcess("glue", [&] { Glue::LoopProcess(system); }); | ||
| 253 | kernel.RunOnGuestCoreProcess("grc", [&] { GRC::LoopProcess(system); }); | ||
| 254 | kernel.RunOnGuestCoreProcess("hid", [&] { HID::LoopProcess(system); }); | ||
| 255 | kernel.RunOnGuestCoreProcess("lbl", [&] { LBL::LoopProcess(system); }); | ||
| 256 | kernel.RunOnGuestCoreProcess("LogManager.Prod", [&] { LM::LoopProcess(system); }); | ||
| 257 | kernel.RunOnGuestCoreProcess("mig", [&] { Migration::LoopProcess(system); }); | ||
| 258 | kernel.RunOnGuestCoreProcess("mii", [&] { Mii::LoopProcess(system); }); | ||
| 259 | kernel.RunOnGuestCoreProcess("mm", [&] { MM::LoopProcess(system); }); | ||
| 260 | kernel.RunOnGuestCoreProcess("mnpp", [&] { MNPP::LoopProcess(system); }); | ||
| 261 | kernel.RunOnGuestCoreProcess("NCM", [&] { NCM::LoopProcess(system); }); | ||
| 262 | kernel.RunOnGuestCoreProcess("nfc", [&] { NFC::LoopProcess(system); }); | ||
| 263 | kernel.RunOnGuestCoreProcess("nfp", [&] { NFP::LoopProcess(system); }); | ||
| 264 | kernel.RunOnGuestCoreProcess("ngc", [&] { NGC::LoopProcess(system); }); | ||
| 265 | kernel.RunOnGuestCoreProcess("nifm", [&] { NIFM::LoopProcess(system); }); | ||
| 266 | kernel.RunOnGuestCoreProcess("nim", [&] { NIM::LoopProcess(system); }); | ||
| 267 | kernel.RunOnGuestCoreProcess("npns", [&] { NPNS::LoopProcess(system); }); | ||
| 268 | kernel.RunOnGuestCoreProcess("ns", [&] { NS::LoopProcess(system); }); | ||
| 269 | kernel.RunOnGuestCoreProcess("olsc", [&] { OLSC::LoopProcess(system); }); | ||
| 270 | kernel.RunOnGuestCoreProcess("omm", [&] { OMM::LoopProcess(system); }); | ||
| 271 | kernel.RunOnGuestCoreProcess("pcie", [&] { PCIe::LoopProcess(system); }); | ||
| 272 | kernel.RunOnGuestCoreProcess("pctl", [&] { PCTL::LoopProcess(system); }); | ||
| 273 | kernel.RunOnGuestCoreProcess("pcv", [&] { PCV::LoopProcess(system); }); | ||
| 274 | kernel.RunOnGuestCoreProcess("prepo", [&] { PlayReport::LoopProcess(system); }); | ||
| 275 | kernel.RunOnGuestCoreProcess("ProcessManager", [&] { PM::LoopProcess(system); }); | ||
| 276 | kernel.RunOnGuestCoreProcess("ptm", [&] { PTM::LoopProcess(system); }); | ||
| 277 | kernel.RunOnGuestCoreProcess("ro", [&] { RO::LoopProcess(system); }); | ||
| 278 | kernel.RunOnGuestCoreProcess("spl", [&] { SPL::LoopProcess(system); }); | ||
| 279 | kernel.RunOnGuestCoreProcess("ssl", [&] { SSL::LoopProcess(system); }); | ||
| 280 | kernel.RunOnGuestCoreProcess("usb", [&] { USB::LoopProcess(system); }); | ||
| 281 | // clang-format on | ||
| 282 | } | ||
| 283 | |||
| 284 | Services::~Services() = default; | ||
| 285 | |||
| 286 | void Services::KillNVNFlinger() { | ||
| 287 | nv_flinger->ShutdownLayers(); | ||
| 288 | } | ||
| 289 | |||
| 290 | } // namespace Service | 154 | } // namespace Service |
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 22d1343d5..36aae1c79 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h | |||
| @@ -28,11 +28,6 @@ namespace FileSystem { | |||
| 28 | class FileSystemController; | 28 | class FileSystemController; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | namespace Nvnflinger { | ||
| 32 | class HosBinderDriverServer; | ||
| 33 | class Nvnflinger; | ||
| 34 | } // namespace Nvnflinger | ||
| 35 | |||
| 36 | namespace SM { | 31 | namespace SM { |
| 37 | class ServiceManager; | 32 | class ServiceManager; |
| 38 | } | 33 | } |
| @@ -236,20 +231,4 @@ private: | |||
| 236 | } | 231 | } |
| 237 | }; | 232 | }; |
| 238 | 233 | ||
| 239 | /** | ||
| 240 | * The purpose of this class is to own any objects that need to be shared across the other service | ||
| 241 | * implementations. Will be torn down when the global system instance is shutdown. | ||
| 242 | */ | ||
| 243 | class Services final { | ||
| 244 | public: | ||
| 245 | explicit Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system); | ||
| 246 | ~Services(); | ||
| 247 | |||
| 248 | void KillNVNFlinger(); | ||
| 249 | |||
| 250 | private: | ||
| 251 | std::unique_ptr<Nvnflinger::HosBinderDriverServer> hos_binder_driver_server; | ||
| 252 | std::unique_ptr<Nvnflinger::Nvnflinger> nv_flinger; | ||
| 253 | }; | ||
| 254 | |||
| 255 | } // namespace Service | 234 | } // namespace Service |
diff --git a/src/core/hle/service/services.cpp b/src/core/hle/service/services.cpp new file mode 100644 index 000000000..d6c6eff50 --- /dev/null +++ b/src/core/hle/service/services.cpp | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/services.h" | ||
| 5 | |||
| 6 | #include "core/hle/service/acc/acc.h" | ||
| 7 | #include "core/hle/service/am/am.h" | ||
| 8 | #include "core/hle/service/aoc/aoc_u.h" | ||
| 9 | #include "core/hle/service/apm/apm.h" | ||
| 10 | #include "core/hle/service/audio/audio.h" | ||
| 11 | #include "core/hle/service/bcat/bcat.h" | ||
| 12 | #include "core/hle/service/bpc/bpc.h" | ||
| 13 | #include "core/hle/service/btdrv/btdrv.h" | ||
| 14 | #include "core/hle/service/btm/btm.h" | ||
| 15 | #include "core/hle/service/caps/caps.h" | ||
| 16 | #include "core/hle/service/erpt/erpt.h" | ||
| 17 | #include "core/hle/service/es/es.h" | ||
| 18 | #include "core/hle/service/eupld/eupld.h" | ||
| 19 | #include "core/hle/service/fatal/fatal.h" | ||
| 20 | #include "core/hle/service/fgm/fgm.h" | ||
| 21 | #include "core/hle/service/filesystem/filesystem.h" | ||
| 22 | #include "core/hle/service/friend/friend.h" | ||
| 23 | #include "core/hle/service/glue/glue.h" | ||
| 24 | #include "core/hle/service/grc/grc.h" | ||
| 25 | #include "core/hle/service/hid/hid.h" | ||
| 26 | #include "core/hle/service/ipc_helpers.h" | ||
| 27 | #include "core/hle/service/jit/jit.h" | ||
| 28 | #include "core/hle/service/lbl/lbl.h" | ||
| 29 | #include "core/hle/service/ldn/ldn.h" | ||
| 30 | #include "core/hle/service/ldr/ldr.h" | ||
| 31 | #include "core/hle/service/lm/lm.h" | ||
| 32 | #include "core/hle/service/mig/mig.h" | ||
| 33 | #include "core/hle/service/mii/mii.h" | ||
| 34 | #include "core/hle/service/mm/mm_u.h" | ||
| 35 | #include "core/hle/service/mnpp/mnpp_app.h" | ||
| 36 | #include "core/hle/service/ncm/ncm.h" | ||
| 37 | #include "core/hle/service/nfc/nfc.h" | ||
| 38 | #include "core/hle/service/nfp/nfp.h" | ||
| 39 | #include "core/hle/service/ngc/ngc.h" | ||
| 40 | #include "core/hle/service/nifm/nifm.h" | ||
| 41 | #include "core/hle/service/nim/nim.h" | ||
| 42 | #include "core/hle/service/npns/npns.h" | ||
| 43 | #include "core/hle/service/ns/ns.h" | ||
| 44 | #include "core/hle/service/nvdrv/nvdrv.h" | ||
| 45 | #include "core/hle/service/nvnflinger/nvnflinger.h" | ||
| 46 | #include "core/hle/service/olsc/olsc.h" | ||
| 47 | #include "core/hle/service/omm/omm.h" | ||
| 48 | #include "core/hle/service/pcie/pcie.h" | ||
| 49 | #include "core/hle/service/pctl/pctl_module.h" | ||
| 50 | #include "core/hle/service/pcv/pcv.h" | ||
| 51 | #include "core/hle/service/pm/pm.h" | ||
| 52 | #include "core/hle/service/prepo/prepo.h" | ||
| 53 | #include "core/hle/service/psc/psc.h" | ||
| 54 | #include "core/hle/service/ptm/ptm.h" | ||
| 55 | #include "core/hle/service/ro/ro.h" | ||
| 56 | #include "core/hle/service/service.h" | ||
| 57 | #include "core/hle/service/set/settings.h" | ||
| 58 | #include "core/hle/service/sm/sm.h" | ||
| 59 | #include "core/hle/service/sockets/sockets.h" | ||
| 60 | #include "core/hle/service/spl/spl_module.h" | ||
| 61 | #include "core/hle/service/ssl/ssl.h" | ||
| 62 | #include "core/hle/service/usb/usb.h" | ||
| 63 | #include "core/hle/service/vi/vi.h" | ||
| 64 | |||
| 65 | namespace Service { | ||
| 66 | |||
| 67 | Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system, | ||
| 68 | std::stop_token token) { | ||
| 69 | auto& kernel = system.Kernel(); | ||
| 70 | |||
| 71 | system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false); | ||
| 72 | |||
| 73 | // clang-format off | ||
| 74 | kernel.RunOnHostCoreProcess("audio", [&] { Audio::LoopProcess(system); }).detach(); | ||
| 75 | kernel.RunOnHostCoreProcess("FS", [&] { FileSystem::LoopProcess(system); }).detach(); | ||
| 76 | kernel.RunOnHostCoreProcess("jit", [&] { JIT::LoopProcess(system); }).detach(); | ||
| 77 | kernel.RunOnHostCoreProcess("ldn", [&] { LDN::LoopProcess(system); }).detach(); | ||
| 78 | kernel.RunOnHostCoreProcess("Loader", [&] { LDR::LoopProcess(system); }).detach(); | ||
| 79 | kernel.RunOnHostCoreProcess("nvservices", [&] { Nvidia::LoopProcess(system); }).detach(); | ||
| 80 | kernel.RunOnHostCoreProcess("bsdsocket", [&] { Sockets::LoopProcess(system); }).detach(); | ||
| 81 | kernel.RunOnHostCoreProcess("vi", [&, token] { VI::LoopProcess(system, token); }).detach(); | ||
| 82 | |||
| 83 | kernel.RunOnGuestCoreProcess("sm", [&] { SM::LoopProcess(system); }); | ||
| 84 | kernel.RunOnGuestCoreProcess("account", [&] { Account::LoopProcess(system); }); | ||
| 85 | kernel.RunOnGuestCoreProcess("am", [&] { AM::LoopProcess(system); }); | ||
| 86 | kernel.RunOnGuestCoreProcess("aoc", [&] { AOC::LoopProcess(system); }); | ||
| 87 | kernel.RunOnGuestCoreProcess("apm", [&] { APM::LoopProcess(system); }); | ||
| 88 | kernel.RunOnGuestCoreProcess("bcat", [&] { BCAT::LoopProcess(system); }); | ||
| 89 | kernel.RunOnGuestCoreProcess("bpc", [&] { BPC::LoopProcess(system); }); | ||
| 90 | kernel.RunOnGuestCoreProcess("btdrv", [&] { BtDrv::LoopProcess(system); }); | ||
| 91 | kernel.RunOnGuestCoreProcess("btm", [&] { BTM::LoopProcess(system); }); | ||
| 92 | kernel.RunOnGuestCoreProcess("capsrv", [&] { Capture::LoopProcess(system); }); | ||
| 93 | kernel.RunOnGuestCoreProcess("erpt", [&] { ERPT::LoopProcess(system); }); | ||
| 94 | kernel.RunOnGuestCoreProcess("es", [&] { ES::LoopProcess(system); }); | ||
| 95 | kernel.RunOnGuestCoreProcess("eupld", [&] { EUPLD::LoopProcess(system); }); | ||
| 96 | kernel.RunOnGuestCoreProcess("fatal", [&] { Fatal::LoopProcess(system); }); | ||
| 97 | kernel.RunOnGuestCoreProcess("fgm", [&] { FGM::LoopProcess(system); }); | ||
| 98 | kernel.RunOnGuestCoreProcess("friends", [&] { Friend::LoopProcess(system); }); | ||
| 99 | kernel.RunOnGuestCoreProcess("settings", [&] { Set::LoopProcess(system); }); | ||
| 100 | kernel.RunOnGuestCoreProcess("psc", [&] { PSC::LoopProcess(system); }); | ||
| 101 | kernel.RunOnGuestCoreProcess("glue", [&] { Glue::LoopProcess(system); }); | ||
| 102 | kernel.RunOnGuestCoreProcess("grc", [&] { GRC::LoopProcess(system); }); | ||
| 103 | kernel.RunOnGuestCoreProcess("hid", [&] { HID::LoopProcess(system); }); | ||
| 104 | kernel.RunOnGuestCoreProcess("lbl", [&] { LBL::LoopProcess(system); }); | ||
| 105 | kernel.RunOnGuestCoreProcess("LogManager.Prod", [&] { LM::LoopProcess(system); }); | ||
| 106 | kernel.RunOnGuestCoreProcess("mig", [&] { Migration::LoopProcess(system); }); | ||
| 107 | kernel.RunOnGuestCoreProcess("mii", [&] { Mii::LoopProcess(system); }); | ||
| 108 | kernel.RunOnGuestCoreProcess("mm", [&] { MM::LoopProcess(system); }); | ||
| 109 | kernel.RunOnGuestCoreProcess("mnpp", [&] { MNPP::LoopProcess(system); }); | ||
| 110 | kernel.RunOnGuestCoreProcess("nvnflinger", [&] { Nvnflinger::LoopProcess(system); }); | ||
| 111 | kernel.RunOnGuestCoreProcess("NCM", [&] { NCM::LoopProcess(system); }); | ||
| 112 | kernel.RunOnGuestCoreProcess("nfc", [&] { NFC::LoopProcess(system); }); | ||
| 113 | kernel.RunOnGuestCoreProcess("nfp", [&] { NFP::LoopProcess(system); }); | ||
| 114 | kernel.RunOnGuestCoreProcess("ngc", [&] { NGC::LoopProcess(system); }); | ||
| 115 | kernel.RunOnGuestCoreProcess("nifm", [&] { NIFM::LoopProcess(system); }); | ||
| 116 | kernel.RunOnGuestCoreProcess("nim", [&] { NIM::LoopProcess(system); }); | ||
| 117 | kernel.RunOnGuestCoreProcess("npns", [&] { NPNS::LoopProcess(system); }); | ||
| 118 | kernel.RunOnGuestCoreProcess("ns", [&] { NS::LoopProcess(system); }); | ||
| 119 | kernel.RunOnGuestCoreProcess("olsc", [&] { OLSC::LoopProcess(system); }); | ||
| 120 | kernel.RunOnGuestCoreProcess("omm", [&] { OMM::LoopProcess(system); }); | ||
| 121 | kernel.RunOnGuestCoreProcess("pcie", [&] { PCIe::LoopProcess(system); }); | ||
| 122 | kernel.RunOnGuestCoreProcess("pctl", [&] { PCTL::LoopProcess(system); }); | ||
| 123 | kernel.RunOnGuestCoreProcess("pcv", [&] { PCV::LoopProcess(system); }); | ||
| 124 | kernel.RunOnGuestCoreProcess("prepo", [&] { PlayReport::LoopProcess(system); }); | ||
| 125 | kernel.RunOnGuestCoreProcess("ProcessManager", [&] { PM::LoopProcess(system); }); | ||
| 126 | kernel.RunOnGuestCoreProcess("ptm", [&] { PTM::LoopProcess(system); }); | ||
| 127 | kernel.RunOnGuestCoreProcess("ro", [&] { RO::LoopProcess(system); }); | ||
| 128 | kernel.RunOnGuestCoreProcess("spl", [&] { SPL::LoopProcess(system); }); | ||
| 129 | kernel.RunOnGuestCoreProcess("ssl", [&] { SSL::LoopProcess(system); }); | ||
| 130 | kernel.RunOnGuestCoreProcess("usb", [&] { USB::LoopProcess(system); }); | ||
| 131 | // clang-format on | ||
| 132 | } | ||
| 133 | |||
| 134 | Services::~Services() = default; | ||
| 135 | |||
| 136 | } // namespace Service | ||
diff --git a/src/core/hle/service/services.h b/src/core/hle/service/services.h new file mode 100644 index 000000000..a99fa1e53 --- /dev/null +++ b/src/core/hle/service/services.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/polyfill_thread.h" | ||
| 7 | #include "core/hle/service/sm/sm.h" | ||
| 8 | |||
| 9 | namespace Service { | ||
| 10 | |||
| 11 | /** | ||
| 12 | * The purpose of this class is to own any objects that need to be shared across the other service | ||
| 13 | * implementations. Will be torn down when the global system instance is shutdown. | ||
| 14 | */ | ||
| 15 | class Services final { | ||
| 16 | public: | ||
| 17 | explicit Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system, | ||
| 18 | std::stop_token token); | ||
| 19 | ~Services(); | ||
| 20 | }; | ||
| 21 | |||
| 22 | } // namespace Service | ||
diff --git a/src/core/hle/service/vi/application_display_service.cpp b/src/core/hle/service/vi/application_display_service.cpp index 78229e30f..6b0bcb536 100644 --- a/src/core/hle/service/vi/application_display_service.cpp +++ b/src/core/hle/service/vi/application_display_service.cpp | |||
| @@ -2,22 +2,21 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/cmif_serialization.h" | 4 | #include "core/hle/service/cmif_serialization.h" |
| 5 | #include "core/hle/service/nvnflinger/nvnflinger.h" | 5 | #include "core/hle/service/nvnflinger/hos_binder_driver.h" |
| 6 | #include "core/hle/service/nvnflinger/parcel.h" | 6 | #include "core/hle/service/nvnflinger/parcel.h" |
| 7 | #include "core/hle/service/os/event.h" | ||
| 7 | #include "core/hle/service/vi/application_display_service.h" | 8 | #include "core/hle/service/vi/application_display_service.h" |
| 8 | #include "core/hle/service/vi/hos_binder_driver.h" | 9 | #include "core/hle/service/vi/container.h" |
| 9 | #include "core/hle/service/vi/manager_display_service.h" | 10 | #include "core/hle/service/vi/manager_display_service.h" |
| 10 | #include "core/hle/service/vi/system_display_service.h" | 11 | #include "core/hle/service/vi/system_display_service.h" |
| 11 | #include "core/hle/service/vi/vi_results.h" | 12 | #include "core/hle/service/vi/vi_results.h" |
| 12 | 13 | ||
| 13 | namespace Service::VI { | 14 | namespace Service::VI { |
| 14 | 15 | ||
| 15 | IApplicationDisplayService::IApplicationDisplayService( | 16 | IApplicationDisplayService::IApplicationDisplayService(Core::System& system_, |
| 16 | Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger, | 17 | std::shared_ptr<Container> container) |
| 17 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server) | 18 | : ServiceFramework{system_, "IApplicationDisplayService"}, |
| 18 | : ServiceFramework{system_, "IApplicationDisplayService"}, m_nvnflinger{nvnflinger}, | 19 | m_container{std::move(container)}, m_context{system, "IApplicationDisplayService"} { |
| 19 | m_hos_binder_driver_server{hos_binder_driver_server} { | ||
| 20 | |||
| 21 | // clang-format off | 20 | // clang-format off |
| 22 | static const FunctionInfo functions[] = { | 21 | static const FunctionInfo functions[] = { |
| 23 | {100, C<&IApplicationDisplayService::GetRelayService>, "GetRelayService"}, | 22 | {100, C<&IApplicationDisplayService::GetRelayService>, "GetRelayService"}, |
| @@ -48,38 +47,41 @@ IApplicationDisplayService::IApplicationDisplayService( | |||
| 48 | } | 47 | } |
| 49 | 48 | ||
| 50 | IApplicationDisplayService::~IApplicationDisplayService() { | 49 | IApplicationDisplayService::~IApplicationDisplayService() { |
| 50 | for (auto& [display_id, event] : m_display_vsync_events) { | ||
| 51 | m_container->UnlinkVsyncEvent(display_id, &event); | ||
| 52 | } | ||
| 53 | for (const auto layer_id : m_open_layer_ids) { | ||
| 54 | m_container->CloseLayer(layer_id); | ||
| 55 | } | ||
| 51 | for (const auto layer_id : m_stray_layer_ids) { | 56 | for (const auto layer_id : m_stray_layer_ids) { |
| 52 | m_nvnflinger.DestroyLayer(layer_id); | 57 | m_container->DestroyStrayLayer(layer_id); |
| 53 | } | 58 | } |
| 54 | } | 59 | } |
| 55 | 60 | ||
| 56 | Result IApplicationDisplayService::GetRelayService( | 61 | Result IApplicationDisplayService::GetRelayService( |
| 57 | Out<SharedPointer<IHOSBinderDriver>> out_relay_service) { | 62 | Out<SharedPointer<Nvnflinger::IHOSBinderDriver>> out_relay_service) { |
| 58 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 63 | LOG_WARNING(Service_VI, "(STUBBED) called"); |
| 59 | *out_relay_service = std::make_shared<IHOSBinderDriver>(system, m_hos_binder_driver_server); | 64 | R_RETURN(m_container->GetBinderDriver(out_relay_service)); |
| 60 | R_SUCCEED(); | ||
| 61 | } | 65 | } |
| 62 | 66 | ||
| 63 | Result IApplicationDisplayService::GetSystemDisplayService( | 67 | Result IApplicationDisplayService::GetSystemDisplayService( |
| 64 | Out<SharedPointer<ISystemDisplayService>> out_system_display_service) { | 68 | Out<SharedPointer<ISystemDisplayService>> out_system_display_service) { |
| 65 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 69 | LOG_WARNING(Service_VI, "(STUBBED) called"); |
| 66 | *out_system_display_service = std::make_shared<ISystemDisplayService>(system, m_nvnflinger); | 70 | *out_system_display_service = std::make_shared<ISystemDisplayService>(system, m_container); |
| 67 | R_SUCCEED(); | 71 | R_SUCCEED(); |
| 68 | } | 72 | } |
| 69 | 73 | ||
| 70 | Result IApplicationDisplayService::GetManagerDisplayService( | 74 | Result IApplicationDisplayService::GetManagerDisplayService( |
| 71 | Out<SharedPointer<IManagerDisplayService>> out_manager_display_service) { | 75 | Out<SharedPointer<IManagerDisplayService>> out_manager_display_service) { |
| 72 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 76 | LOG_WARNING(Service_VI, "(STUBBED) called"); |
| 73 | *out_manager_display_service = std::make_shared<IManagerDisplayService>(system, m_nvnflinger); | 77 | *out_manager_display_service = std::make_shared<IManagerDisplayService>(system, m_container); |
| 74 | R_SUCCEED(); | 78 | R_SUCCEED(); |
| 75 | } | 79 | } |
| 76 | 80 | ||
| 77 | Result IApplicationDisplayService::GetIndirectDisplayTransactionService( | 81 | Result IApplicationDisplayService::GetIndirectDisplayTransactionService( |
| 78 | Out<SharedPointer<IHOSBinderDriver>> out_indirect_display_transaction_service) { | 82 | Out<SharedPointer<Nvnflinger::IHOSBinderDriver>> out_indirect_display_transaction_service) { |
| 79 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 83 | LOG_WARNING(Service_VI, "(STUBBED) called"); |
| 80 | *out_indirect_display_transaction_service = | 84 | R_RETURN(m_container->GetBinderDriver(out_indirect_display_transaction_service)); |
| 81 | std::make_shared<IHOSBinderDriver>(system, m_hos_binder_driver_server); | ||
| 82 | R_SUCCEED(); | ||
| 83 | } | 85 | } |
| 84 | 86 | ||
| 85 | Result IApplicationDisplayService::OpenDisplay(Out<u64> out_display_id, DisplayName display_name) { | 87 | Result IApplicationDisplayService::OpenDisplay(Out<u64> out_display_id, DisplayName display_name) { |
| @@ -89,14 +91,7 @@ Result IApplicationDisplayService::OpenDisplay(Out<u64> out_display_id, DisplayN | |||
| 89 | ASSERT_MSG(strcmp(display_name.data(), "Default") == 0, | 91 | ASSERT_MSG(strcmp(display_name.data(), "Default") == 0, |
| 90 | "Non-default displays aren't supported yet"); | 92 | "Non-default displays aren't supported yet"); |
| 91 | 93 | ||
| 92 | const auto display_id = m_nvnflinger.OpenDisplay(display_name.data()); | 94 | R_RETURN(m_container->OpenDisplay(out_display_id, display_name)); |
| 93 | if (!display_id) { | ||
| 94 | LOG_ERROR(Service_VI, "Display not found! display_name={}", display_name.data()); | ||
| 95 | R_THROW(VI::ResultNotFound); | ||
| 96 | } | ||
| 97 | |||
| 98 | *out_display_id = *display_id; | ||
| 99 | R_SUCCEED(); | ||
| 100 | } | 95 | } |
| 101 | 96 | ||
| 102 | Result IApplicationDisplayService::OpenDefaultDisplay(Out<u64> out_display_id) { | 97 | Result IApplicationDisplayService::OpenDefaultDisplay(Out<u64> out_display_id) { |
| @@ -106,8 +101,7 @@ Result IApplicationDisplayService::OpenDefaultDisplay(Out<u64> out_display_id) { | |||
| 106 | 101 | ||
| 107 | Result IApplicationDisplayService::CloseDisplay(u64 display_id) { | 102 | Result IApplicationDisplayService::CloseDisplay(u64 display_id) { |
| 108 | LOG_DEBUG(Service_VI, "called"); | 103 | LOG_DEBUG(Service_VI, "called"); |
| 109 | R_SUCCEED_IF(m_nvnflinger.CloseDisplay(display_id)); | 104 | R_RETURN(m_container->CloseDisplay(display_id)); |
| 110 | R_THROW(ResultUnknown); | ||
| 111 | } | 105 | } |
| 112 | 106 | ||
| 113 | Result IApplicationDisplayService::SetDisplayEnabled(u32 state, u64 display_id) { | 107 | Result IApplicationDisplayService::SetDisplayEnabled(u32 state, u64 display_id) { |
| @@ -168,25 +162,19 @@ Result IApplicationDisplayService::OpenLayer(Out<u64> out_size, | |||
| 168 | 162 | ||
| 169 | LOG_DEBUG(Service_VI, "called. layer_id={}, aruid={:#x}", layer_id, aruid.pid); | 163 | LOG_DEBUG(Service_VI, "called. layer_id={}, aruid={:#x}", layer_id, aruid.pid); |
| 170 | 164 | ||
| 171 | const auto display_id = m_nvnflinger.OpenDisplay(display_name.data()); | 165 | u64 display_id; |
| 172 | if (!display_id) { | 166 | R_TRY(m_container->OpenDisplay(&display_id, display_name)); |
| 173 | LOG_ERROR(Service_VI, "Layer not found! layer_id={}", layer_id); | ||
| 174 | R_THROW(VI::ResultNotFound); | ||
| 175 | } | ||
| 176 | 167 | ||
| 177 | const auto buffer_queue_id = m_nvnflinger.FindBufferQueueId(*display_id, layer_id); | 168 | s32 producer_binder_id; |
| 178 | if (!buffer_queue_id) { | 169 | R_TRY(m_container->OpenLayer(&producer_binder_id, layer_id, aruid.pid)); |
| 179 | LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", *display_id); | ||
| 180 | R_THROW(VI::ResultNotFound); | ||
| 181 | } | ||
| 182 | 170 | ||
| 183 | if (!m_nvnflinger.OpenLayer(layer_id)) { | 171 | { |
| 184 | LOG_WARNING(Service_VI, "Tried to open layer which was already open"); | 172 | std::scoped_lock lk{m_lock}; |
| 185 | R_THROW(VI::ResultOperationFailed); | 173 | m_open_layer_ids.insert(layer_id); |
| 186 | } | 174 | } |
| 187 | 175 | ||
| 188 | android::OutputParcel parcel; | 176 | android::OutputParcel parcel; |
| 189 | parcel.WriteInterface(NativeWindow{*buffer_queue_id}); | 177 | parcel.WriteInterface(NativeWindow{producer_binder_id}); |
| 190 | 178 | ||
| 191 | const auto buffer = parcel.Serialize(); | 179 | const auto buffer = parcel.Serialize(); |
| 192 | std::memcpy(out_native_window.data(), buffer.data(), | 180 | std::memcpy(out_native_window.data(), buffer.data(), |
| @@ -199,12 +187,13 @@ Result IApplicationDisplayService::OpenLayer(Out<u64> out_size, | |||
| 199 | Result IApplicationDisplayService::CloseLayer(u64 layer_id) { | 187 | Result IApplicationDisplayService::CloseLayer(u64 layer_id) { |
| 200 | LOG_DEBUG(Service_VI, "called. layer_id={}", layer_id); | 188 | LOG_DEBUG(Service_VI, "called. layer_id={}", layer_id); |
| 201 | 189 | ||
| 202 | if (!m_nvnflinger.CloseLayer(layer_id)) { | 190 | { |
| 203 | LOG_WARNING(Service_VI, "Tried to close layer which was not open"); | 191 | std::scoped_lock lk{m_lock}; |
| 204 | R_THROW(VI::ResultOperationFailed); | 192 | R_UNLESS(m_open_layer_ids.contains(layer_id), VI::ResultNotFound); |
| 193 | m_open_layer_ids.erase(layer_id); | ||
| 205 | } | 194 | } |
| 206 | 195 | ||
| 207 | R_SUCCEED(); | 196 | R_RETURN(m_container->CloseLayer(layer_id)); |
| 208 | } | 197 | } |
| 209 | 198 | ||
| 210 | Result IApplicationDisplayService::CreateStrayLayer( | 199 | Result IApplicationDisplayService::CreateStrayLayer( |
| @@ -212,27 +201,19 @@ Result IApplicationDisplayService::CreateStrayLayer( | |||
| 212 | u32 flags, u64 display_id) { | 201 | u32 flags, u64 display_id) { |
| 213 | LOG_DEBUG(Service_VI, "called. flags={}, display_id={}", flags, display_id); | 202 | LOG_DEBUG(Service_VI, "called. flags={}, display_id={}", flags, display_id); |
| 214 | 203 | ||
| 215 | const auto layer_id = m_nvnflinger.CreateLayer(display_id); | 204 | s32 producer_binder_id; |
| 216 | if (!layer_id) { | 205 | R_TRY(m_container->CreateStrayLayer(&producer_binder_id, out_layer_id, display_id)); |
| 217 | LOG_ERROR(Service_VI, "Layer not found! display_id={}", display_id); | ||
| 218 | R_THROW(VI::ResultNotFound); | ||
| 219 | } | ||
| 220 | 206 | ||
| 221 | m_stray_layer_ids.push_back(*layer_id); | 207 | std::scoped_lock lk{m_lock}; |
| 222 | const auto buffer_queue_id = m_nvnflinger.FindBufferQueueId(display_id, *layer_id); | 208 | m_stray_layer_ids.insert(*out_layer_id); |
| 223 | if (!buffer_queue_id) { | ||
| 224 | LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", display_id); | ||
| 225 | R_THROW(VI::ResultNotFound); | ||
| 226 | } | ||
| 227 | 209 | ||
| 228 | android::OutputParcel parcel; | 210 | android::OutputParcel parcel; |
| 229 | parcel.WriteInterface(NativeWindow{*buffer_queue_id}); | 211 | parcel.WriteInterface(NativeWindow{producer_binder_id}); |
| 230 | 212 | ||
| 231 | const auto buffer = parcel.Serialize(); | 213 | const auto buffer = parcel.Serialize(); |
| 232 | std::memcpy(out_native_window.data(), buffer.data(), | 214 | std::memcpy(out_native_window.data(), buffer.data(), |
| 233 | std::min(out_native_window.size(), buffer.size())); | 215 | std::min(out_native_window.size(), buffer.size())); |
| 234 | 216 | ||
| 235 | *out_layer_id = *layer_id; | ||
| 236 | *out_size = buffer.size(); | 217 | *out_size = buffer.size(); |
| 237 | 218 | ||
| 238 | R_SUCCEED(); | 219 | R_SUCCEED(); |
| @@ -240,25 +221,27 @@ Result IApplicationDisplayService::CreateStrayLayer( | |||
| 240 | 221 | ||
| 241 | Result IApplicationDisplayService::DestroyStrayLayer(u64 layer_id) { | 222 | Result IApplicationDisplayService::DestroyStrayLayer(u64 layer_id) { |
| 242 | LOG_WARNING(Service_VI, "(STUBBED) called. layer_id={}", layer_id); | 223 | LOG_WARNING(Service_VI, "(STUBBED) called. layer_id={}", layer_id); |
| 243 | m_nvnflinger.DestroyLayer(layer_id); | 224 | |
| 244 | R_SUCCEED(); | 225 | { |
| 226 | std::scoped_lock lk{m_lock}; | ||
| 227 | R_UNLESS(m_stray_layer_ids.contains(layer_id), VI::ResultNotFound); | ||
| 228 | m_stray_layer_ids.erase(layer_id); | ||
| 229 | } | ||
| 230 | |||
| 231 | R_RETURN(m_container->DestroyStrayLayer(layer_id)); | ||
| 245 | } | 232 | } |
| 246 | 233 | ||
| 247 | Result IApplicationDisplayService::GetDisplayVsyncEvent( | 234 | Result IApplicationDisplayService::GetDisplayVsyncEvent( |
| 248 | OutCopyHandle<Kernel::KReadableEvent> out_vsync_event, u64 display_id) { | 235 | OutCopyHandle<Kernel::KReadableEvent> out_vsync_event, u64 display_id) { |
| 249 | LOG_DEBUG(Service_VI, "called. display_id={}", display_id); | 236 | LOG_DEBUG(Service_VI, "called. display_id={}", display_id); |
| 250 | 237 | ||
| 251 | const auto result = m_nvnflinger.FindVsyncEvent(out_vsync_event, display_id); | 238 | std::scoped_lock lk{m_lock}; |
| 252 | if (result != ResultSuccess) { | ||
| 253 | if (result == ResultNotFound) { | ||
| 254 | LOG_ERROR(Service_VI, "Vsync event was not found for display_id={}", display_id); | ||
| 255 | } | ||
| 256 | 239 | ||
| 257 | R_THROW(result); | 240 | auto [it, created] = m_display_vsync_events.emplace(display_id, m_context); |
| 258 | } | 241 | R_UNLESS(created, VI::ResultPermissionDenied); |
| 259 | 242 | ||
| 260 | R_UNLESS(!m_vsync_event_fetched, VI::ResultPermissionDenied); | 243 | m_container->LinkVsyncEvent(display_id, &it->second); |
| 261 | m_vsync_event_fetched = true; | 244 | *out_vsync_event = it->second.GetHandle(); |
| 262 | 245 | ||
| 263 | R_SUCCEED(); | 246 | R_SUCCEED(); |
| 264 | } | 247 | } |
diff --git a/src/core/hle/service/vi/application_display_service.h b/src/core/hle/service/vi/application_display_service.h index 5dff4bb31..1bdeb8f84 100644 --- a/src/core/hle/service/vi/application_display_service.h +++ b/src/core/hle/service/vi/application_display_service.h | |||
| @@ -1,7 +1,12 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include <map> | ||
| 5 | #include <set> | ||
| 6 | |||
| 4 | #include "core/hle/service/cmif_types.h" | 7 | #include "core/hle/service/cmif_types.h" |
| 8 | #include "core/hle/service/kernel_helpers.h" | ||
| 9 | #include "core/hle/service/os/event.h" | ||
| 5 | #include "core/hle/service/service.h" | 10 | #include "core/hle/service/service.h" |
| 6 | #include "core/hle/service/vi/vi_types.h" | 11 | #include "core/hle/service/vi/vi_types.h" |
| 7 | 12 | ||
| @@ -9,26 +14,33 @@ namespace Kernel { | |||
| 9 | class KReadableEvent; | 14 | class KReadableEvent; |
| 10 | } | 15 | } |
| 11 | 16 | ||
| 17 | namespace Service::Nvnflinger { | ||
| 18 | class IHOSBinderDriver; | ||
| 19 | } | ||
| 20 | |||
| 12 | namespace Service::VI { | 21 | namespace Service::VI { |
| 13 | 22 | ||
| 14 | class IHOSBinderDriver; | 23 | class Container; |
| 15 | class IManagerDisplayService; | 24 | class IManagerDisplayService; |
| 16 | class ISystemDisplayService; | 25 | class ISystemDisplayService; |
| 17 | 26 | ||
| 18 | class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> { | 27 | class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> { |
| 19 | public: | 28 | public: |
| 20 | IApplicationDisplayService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger, | 29 | IApplicationDisplayService(Core::System& system_, std::shared_ptr<Container> container); |
| 21 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server); | ||
| 22 | ~IApplicationDisplayService() override; | 30 | ~IApplicationDisplayService() override; |
| 23 | 31 | ||
| 24 | private: | 32 | std::shared_ptr<Container> GetContainer() const { |
| 25 | Result GetRelayService(Out<SharedPointer<IHOSBinderDriver>> out_relay_service); | 33 | return m_container; |
| 34 | } | ||
| 35 | |||
| 36 | public: | ||
| 37 | Result GetRelayService(Out<SharedPointer<Nvnflinger::IHOSBinderDriver>> out_relay_service); | ||
| 26 | Result GetSystemDisplayService( | 38 | Result GetSystemDisplayService( |
| 27 | Out<SharedPointer<ISystemDisplayService>> out_system_display_service); | 39 | Out<SharedPointer<ISystemDisplayService>> out_system_display_service); |
| 28 | Result GetManagerDisplayService( | 40 | Result GetManagerDisplayService( |
| 29 | Out<SharedPointer<IManagerDisplayService>> out_manager_display_service); | 41 | Out<SharedPointer<IManagerDisplayService>> out_manager_display_service); |
| 30 | Result GetIndirectDisplayTransactionService( | 42 | Result GetIndirectDisplayTransactionService( |
| 31 | Out<SharedPointer<IHOSBinderDriver>> out_indirect_display_transaction_service); | 43 | Out<SharedPointer<Nvnflinger::IHOSBinderDriver>> out_indirect_display_transaction_service); |
| 32 | Result OpenDisplay(Out<u64> out_display_id, DisplayName display_name); | 44 | Result OpenDisplay(Out<u64> out_display_id, DisplayName display_name); |
| 33 | Result OpenDefaultDisplay(Out<u64> out_display_id); | 45 | Result OpenDefaultDisplay(Out<u64> out_display_id); |
| 34 | Result CloseDisplay(u64 display_id); | 46 | Result CloseDisplay(u64 display_id); |
| @@ -56,9 +68,13 @@ private: | |||
| 56 | s64 width, s64 height); | 68 | s64 width, s64 height); |
| 57 | 69 | ||
| 58 | private: | 70 | private: |
| 59 | Nvnflinger::Nvnflinger& m_nvnflinger; | 71 | const std::shared_ptr<Container> m_container; |
| 60 | Nvnflinger::HosBinderDriverServer& m_hos_binder_driver_server; | 72 | |
| 61 | std::vector<u64> m_stray_layer_ids; | 73 | KernelHelpers::ServiceContext m_context; |
| 74 | std::mutex m_lock{}; | ||
| 75 | std::set<u64> m_open_layer_ids{}; | ||
| 76 | std::set<u64> m_stray_layer_ids{}; | ||
| 77 | std::map<u64, Event> m_display_vsync_events{}; | ||
| 62 | bool m_vsync_event_fetched{false}; | 78 | bool m_vsync_event_fetched{false}; |
| 63 | }; | 79 | }; |
| 64 | 80 | ||
diff --git a/src/core/hle/service/vi/application_root_service.cpp b/src/core/hle/service/vi/application_root_service.cpp index 7af7f062c..7f35a048d 100644 --- a/src/core/hle/service/vi/application_root_service.cpp +++ b/src/core/hle/service/vi/application_root_service.cpp | |||
| @@ -4,17 +4,16 @@ | |||
| 4 | #include "core/hle/service/cmif_serialization.h" | 4 | #include "core/hle/service/cmif_serialization.h" |
| 5 | #include "core/hle/service/vi/application_display_service.h" | 5 | #include "core/hle/service/vi/application_display_service.h" |
| 6 | #include "core/hle/service/vi/application_root_service.h" | 6 | #include "core/hle/service/vi/application_root_service.h" |
| 7 | #include "core/hle/service/vi/container.h" | ||
| 7 | #include "core/hle/service/vi/service_creator.h" | 8 | #include "core/hle/service/vi/service_creator.h" |
| 8 | #include "core/hle/service/vi/vi.h" | 9 | #include "core/hle/service/vi/vi.h" |
| 9 | #include "core/hle/service/vi/vi_types.h" | 10 | #include "core/hle/service/vi/vi_types.h" |
| 10 | 11 | ||
| 11 | namespace Service::VI { | 12 | namespace Service::VI { |
| 12 | 13 | ||
| 13 | IApplicationRootService::IApplicationRootService( | 14 | IApplicationRootService::IApplicationRootService(Core::System& system_, |
| 14 | Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger, | 15 | std::shared_ptr<Container> container) |
| 15 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server) | 16 | : ServiceFramework{system_, "vi:u"}, m_container{std::move(container)} { |
| 16 | : ServiceFramework{system_, "vi:u"}, m_nvnflinger{nvnflinger}, m_hos_binder_driver_server{ | ||
| 17 | hos_binder_driver_server} { | ||
| 18 | static const FunctionInfo functions[] = { | 17 | static const FunctionInfo functions[] = { |
| 19 | {0, C<&IApplicationRootService::GetDisplayService>, "GetDisplayService"}, | 18 | {0, C<&IApplicationRootService::GetDisplayService>, "GetDisplayService"}, |
| 20 | {1, nullptr, "GetDisplayServiceWithProxyNameExchange"}, | 19 | {1, nullptr, "GetDisplayServiceWithProxyNameExchange"}, |
| @@ -27,8 +26,8 @@ IApplicationRootService::~IApplicationRootService() = default; | |||
| 27 | Result IApplicationRootService::GetDisplayService( | 26 | Result IApplicationRootService::GetDisplayService( |
| 28 | Out<SharedPointer<IApplicationDisplayService>> out_application_display_service, Policy policy) { | 27 | Out<SharedPointer<IApplicationDisplayService>> out_application_display_service, Policy policy) { |
| 29 | LOG_DEBUG(Service_VI, "called"); | 28 | LOG_DEBUG(Service_VI, "called"); |
| 30 | R_RETURN(GetApplicationDisplayService(out_application_display_service, system, m_nvnflinger, | 29 | R_RETURN(GetApplicationDisplayService(out_application_display_service, system, m_container, |
| 31 | m_hos_binder_driver_server, Permission::User, policy)); | 30 | Permission::User, policy)); |
| 32 | } | 31 | } |
| 33 | 32 | ||
| 34 | } // namespace Service::VI | 33 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/application_root_service.h b/src/core/hle/service/vi/application_root_service.h index 9dbf28cb4..15aa4483d 100644 --- a/src/core/hle/service/vi/application_root_service.h +++ b/src/core/hle/service/vi/application_root_service.h | |||
| @@ -10,20 +10,15 @@ namespace Core { | |||
| 10 | class System; | 10 | class System; |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | namespace Service::Nvnflinger { | ||
| 14 | class HosBinderDriverServer; | ||
| 15 | class Nvnflinger; | ||
| 16 | } // namespace Service::Nvnflinger | ||
| 17 | |||
| 18 | namespace Service::VI { | 13 | namespace Service::VI { |
| 19 | 14 | ||
| 15 | class Container; | ||
| 20 | class IApplicationDisplayService; | 16 | class IApplicationDisplayService; |
| 21 | enum class Policy : u32; | 17 | enum class Policy : u32; |
| 22 | 18 | ||
| 23 | class IApplicationRootService final : public ServiceFramework<IApplicationRootService> { | 19 | class IApplicationRootService final : public ServiceFramework<IApplicationRootService> { |
| 24 | public: | 20 | public: |
| 25 | explicit IApplicationRootService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger, | 21 | explicit IApplicationRootService(Core::System& system_, std::shared_ptr<Container> container); |
| 26 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server); | ||
| 27 | ~IApplicationRootService() override; | 22 | ~IApplicationRootService() override; |
| 28 | 23 | ||
| 29 | private: | 24 | private: |
| @@ -32,8 +27,7 @@ private: | |||
| 32 | Policy policy); | 27 | Policy policy); |
| 33 | 28 | ||
| 34 | private: | 29 | private: |
| 35 | Nvnflinger::Nvnflinger& m_nvnflinger; | 30 | const std::shared_ptr<Container> m_container; |
| 36 | Nvnflinger::HosBinderDriverServer& m_hos_binder_driver_server; | ||
| 37 | }; | 31 | }; |
| 38 | 32 | ||
| 39 | } // namespace Service::VI | 33 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/conductor.cpp b/src/core/hle/service/vi/conductor.cpp new file mode 100644 index 000000000..c8ce4fca0 --- /dev/null +++ b/src/core/hle/service/vi/conductor.cpp | |||
| @@ -0,0 +1,114 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/settings.h" | ||
| 5 | #include "core/core.h" | ||
| 6 | #include "core/core_timing.h" | ||
| 7 | #include "core/hle/service/vi/conductor.h" | ||
| 8 | #include "core/hle/service/vi/container.h" | ||
| 9 | #include "core/hle/service/vi/display_list.h" | ||
| 10 | #include "core/hle/service/vi/vsync_manager.h" | ||
| 11 | |||
| 12 | constexpr auto FrameNs = std::chrono::nanoseconds{1000000000 / 60}; | ||
| 13 | |||
| 14 | namespace Service::VI { | ||
| 15 | |||
| 16 | Conductor::Conductor(Core::System& system, Container& container, DisplayList& displays) | ||
| 17 | : m_system(system), m_container(container) { | ||
| 18 | displays.ForEachDisplay([&](Display& display) { | ||
| 19 | m_vsync_managers.insert({display.GetId(), VsyncManager{}}); | ||
| 20 | }); | ||
| 21 | |||
| 22 | if (system.IsMulticore()) { | ||
| 23 | m_event = Core::Timing::CreateEvent( | ||
| 24 | "ScreenComposition", | ||
| 25 | [this](s64 time, | ||
| 26 | std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 27 | m_signal.Set(); | ||
| 28 | return std::chrono::nanoseconds(this->GetNextTicks()); | ||
| 29 | }); | ||
| 30 | |||
| 31 | system.CoreTiming().ScheduleLoopingEvent(FrameNs, FrameNs, m_event); | ||
| 32 | m_thread = std::jthread([this](std::stop_token token) { this->VsyncThread(token); }); | ||
| 33 | } else { | ||
| 34 | m_event = Core::Timing::CreateEvent( | ||
| 35 | "ScreenComposition", | ||
| 36 | [this](s64 time, | ||
| 37 | std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 38 | this->ProcessVsync(); | ||
| 39 | return std::chrono::nanoseconds(this->GetNextTicks()); | ||
| 40 | }); | ||
| 41 | |||
| 42 | system.CoreTiming().ScheduleLoopingEvent(FrameNs, FrameNs, m_event); | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | Conductor::~Conductor() { | ||
| 47 | m_system.CoreTiming().UnscheduleEvent(m_event); | ||
| 48 | |||
| 49 | if (m_system.IsMulticore()) { | ||
| 50 | m_thread.request_stop(); | ||
| 51 | m_signal.Set(); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | void Conductor::LinkVsyncEvent(u64 display_id, Event* event) { | ||
| 56 | if (auto it = m_vsync_managers.find(display_id); it != m_vsync_managers.end()) { | ||
| 57 | it->second.LinkVsyncEvent(event); | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | void Conductor::UnlinkVsyncEvent(u64 display_id, Event* event) { | ||
| 62 | if (auto it = m_vsync_managers.find(display_id); it != m_vsync_managers.end()) { | ||
| 63 | it->second.UnlinkVsyncEvent(event); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | void Conductor::ProcessVsync() { | ||
| 68 | for (auto& [display_id, manager] : m_vsync_managers) { | ||
| 69 | m_container.ComposeOnDisplay(&m_swap_interval, &m_compose_speed_scale, display_id); | ||
| 70 | manager.SignalVsync(); | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | void Conductor::VsyncThread(std::stop_token token) { | ||
| 75 | Common::SetCurrentThreadName("VSyncThread"); | ||
| 76 | |||
| 77 | while (!token.stop_requested()) { | ||
| 78 | m_signal.Wait(); | ||
| 79 | |||
| 80 | if (m_system.IsShuttingDown()) { | ||
| 81 | return; | ||
| 82 | } | ||
| 83 | |||
| 84 | this->ProcessVsync(); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | s64 Conductor::GetNextTicks() const { | ||
| 89 | const auto& settings = Settings::values; | ||
| 90 | auto speed_scale = 1.f; | ||
| 91 | if (settings.use_multi_core.GetValue()) { | ||
| 92 | if (settings.use_speed_limit.GetValue()) { | ||
| 93 | // Scales the speed based on speed_limit setting on MC. SC is handled by | ||
| 94 | // SpeedLimiter::DoSpeedLimiting. | ||
| 95 | speed_scale = 100.f / settings.speed_limit.GetValue(); | ||
| 96 | } else { | ||
| 97 | // Run at unlocked framerate. | ||
| 98 | speed_scale = 0.01f; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | // Adjust by speed limit determined during composition. | ||
| 103 | speed_scale /= m_compose_speed_scale; | ||
| 104 | |||
| 105 | if (m_system.GetNVDECActive() && settings.use_video_framerate.GetValue()) { | ||
| 106 | // Run at intended presentation rate during video playback. | ||
| 107 | speed_scale = 1.f; | ||
| 108 | } | ||
| 109 | |||
| 110 | const f32 effective_fps = 60.f / static_cast<f32>(m_swap_interval); | ||
| 111 | return static_cast<s64>(speed_scale * (1000000000.f / effective_fps)); | ||
| 112 | } | ||
| 113 | |||
| 114 | } // namespace Service::VI | ||
diff --git a/src/core/hle/service/vi/conductor.h b/src/core/hle/service/vi/conductor.h new file mode 100644 index 000000000..52e3595d2 --- /dev/null +++ b/src/core/hle/service/vi/conductor.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <memory> | ||
| 7 | #include <unordered_map> | ||
| 8 | |||
| 9 | #include "common/common_types.h" | ||
| 10 | #include "common/polyfill_thread.h" | ||
| 11 | #include "common/thread.h" | ||
| 12 | |||
| 13 | namespace Core { | ||
| 14 | class System; | ||
| 15 | } | ||
| 16 | |||
| 17 | namespace Core::Timing { | ||
| 18 | struct EventType; | ||
| 19 | } | ||
| 20 | |||
| 21 | namespace Service { | ||
| 22 | class Event; | ||
| 23 | } | ||
| 24 | |||
| 25 | namespace Service::VI { | ||
| 26 | |||
| 27 | class Container; | ||
| 28 | class DisplayList; | ||
| 29 | class VsyncManager; | ||
| 30 | |||
| 31 | class Conductor { | ||
| 32 | public: | ||
| 33 | explicit Conductor(Core::System& system, Container& container, DisplayList& displays); | ||
| 34 | ~Conductor(); | ||
| 35 | |||
| 36 | void LinkVsyncEvent(u64 display_id, Event* event); | ||
| 37 | void UnlinkVsyncEvent(u64 display_id, Event* event); | ||
| 38 | |||
| 39 | private: | ||
| 40 | void ProcessVsync(); | ||
| 41 | void VsyncThread(std::stop_token token); | ||
| 42 | s64 GetNextTicks() const; | ||
| 43 | |||
| 44 | private: | ||
| 45 | Core::System& m_system; | ||
| 46 | Container& m_container; | ||
| 47 | std::unordered_map<u64, VsyncManager> m_vsync_managers; | ||
| 48 | std::shared_ptr<Core::Timing::EventType> m_event; | ||
| 49 | Common::Event m_signal; | ||
| 50 | std::jthread m_thread; | ||
| 51 | |||
| 52 | private: | ||
| 53 | s32 m_swap_interval = 1; | ||
| 54 | f32 m_compose_speed_scale = 1.0f; | ||
| 55 | }; | ||
| 56 | |||
| 57 | } // namespace Service::VI | ||
diff --git a/src/core/hle/service/vi/container.cpp b/src/core/hle/service/vi/container.cpp new file mode 100644 index 000000000..9074f4ae0 --- /dev/null +++ b/src/core/hle/service/vi/container.cpp | |||
| @@ -0,0 +1,226 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/core.h" | ||
| 5 | #include "core/hle/service/nvdrv/nvdrv_interface.h" | ||
| 6 | #include "core/hle/service/nvnflinger/buffer_queue_producer.h" | ||
| 7 | #include "core/hle/service/nvnflinger/hos_binder_driver.h" | ||
| 8 | #include "core/hle/service/nvnflinger/hos_binder_driver_server.h" | ||
| 9 | #include "core/hle/service/nvnflinger/surface_flinger.h" | ||
| 10 | #include "core/hle/service/sm/sm.h" | ||
| 11 | #include "core/hle/service/vi/container.h" | ||
| 12 | #include "core/hle/service/vi/vi_results.h" | ||
| 13 | |||
| 14 | namespace Service::VI { | ||
| 15 | |||
| 16 | Container::Container(Core::System& system) { | ||
| 17 | m_displays.CreateDisplay(DisplayName{"Default"}); | ||
| 18 | m_displays.CreateDisplay(DisplayName{"External"}); | ||
| 19 | m_displays.CreateDisplay(DisplayName{"Edid"}); | ||
| 20 | m_displays.CreateDisplay(DisplayName{"Internal"}); | ||
| 21 | m_displays.CreateDisplay(DisplayName{"Null"}); | ||
| 22 | |||
| 23 | m_binder_driver = | ||
| 24 | system.ServiceManager().GetService<Nvnflinger::IHOSBinderDriver>("dispdrv", true); | ||
| 25 | m_surface_flinger = m_binder_driver->GetSurfaceFlinger(); | ||
| 26 | |||
| 27 | const auto nvdrv = | ||
| 28 | system.ServiceManager().GetService<Nvidia::NVDRV>("nvdrv:s", true)->GetModule(); | ||
| 29 | m_shared_buffer_manager.emplace(system, *this, nvdrv); | ||
| 30 | |||
| 31 | m_displays.ForEachDisplay( | ||
| 32 | [&](auto& display) { m_surface_flinger->AddDisplay(display.GetId()); }); | ||
| 33 | |||
| 34 | m_conductor.emplace(system, *this, m_displays); | ||
| 35 | } | ||
| 36 | |||
| 37 | Container::~Container() { | ||
| 38 | this->OnTerminate(); | ||
| 39 | } | ||
| 40 | |||
| 41 | void Container::OnTerminate() { | ||
| 42 | std::scoped_lock lk{m_lock}; | ||
| 43 | |||
| 44 | m_is_shut_down = true; | ||
| 45 | |||
| 46 | m_layers.ForEachLayer([&](auto& layer) { this->DestroyLayerLocked(layer.GetId()); }); | ||
| 47 | |||
| 48 | m_displays.ForEachDisplay( | ||
| 49 | [&](auto& display) { m_surface_flinger->RemoveDisplay(display.GetId()); }); | ||
| 50 | } | ||
| 51 | |||
| 52 | SharedBufferManager* Container::GetSharedBufferManager() { | ||
| 53 | return std::addressof(*m_shared_buffer_manager); | ||
| 54 | } | ||
| 55 | |||
| 56 | Result Container::GetBinderDriver( | ||
| 57 | std::shared_ptr<Nvnflinger::IHOSBinderDriver>* out_binder_driver) { | ||
| 58 | *out_binder_driver = m_binder_driver; | ||
| 59 | R_SUCCEED(); | ||
| 60 | } | ||
| 61 | |||
| 62 | Result Container::GetLayerProducerHandle( | ||
| 63 | std::shared_ptr<android::BufferQueueProducer>* out_producer, u64 layer_id) { | ||
| 64 | std::scoped_lock lk{m_lock}; | ||
| 65 | |||
| 66 | auto* const layer = m_layers.GetLayerById(layer_id); | ||
| 67 | R_UNLESS(layer != nullptr, VI::ResultNotFound); | ||
| 68 | |||
| 69 | const auto binder = m_binder_driver->GetServer()->TryGetBinder(layer->GetProducerBinderId()); | ||
| 70 | R_UNLESS(binder != nullptr, VI::ResultNotFound); | ||
| 71 | |||
| 72 | *out_producer = std::static_pointer_cast<android::BufferQueueProducer>(binder); | ||
| 73 | R_SUCCEED(); | ||
| 74 | } | ||
| 75 | |||
| 76 | Result Container::OpenDisplay(u64* out_display_id, const DisplayName& display_name) { | ||
| 77 | auto* const display = m_displays.GetDisplayByName(display_name); | ||
| 78 | R_UNLESS(display != nullptr, VI::ResultNotFound); | ||
| 79 | |||
| 80 | *out_display_id = display->GetId(); | ||
| 81 | R_SUCCEED(); | ||
| 82 | } | ||
| 83 | |||
| 84 | Result Container::CloseDisplay(u64 display_id) { | ||
| 85 | R_SUCCEED(); | ||
| 86 | } | ||
| 87 | |||
| 88 | Result Container::CreateManagedLayer(u64* out_layer_id, u64 display_id, u64 owner_aruid) { | ||
| 89 | std::scoped_lock lk{m_lock}; | ||
| 90 | R_RETURN(this->CreateLayerLocked(out_layer_id, display_id, owner_aruid)); | ||
| 91 | } | ||
| 92 | |||
| 93 | Result Container::DestroyManagedLayer(u64 layer_id) { | ||
| 94 | std::scoped_lock lk{m_lock}; | ||
| 95 | |||
| 96 | // Try to close, if open, but don't fail if not. | ||
| 97 | this->CloseLayerLocked(layer_id); | ||
| 98 | |||
| 99 | R_RETURN(this->DestroyLayerLocked(layer_id)); | ||
| 100 | } | ||
| 101 | |||
| 102 | Result Container::OpenLayer(s32* out_producer_binder_id, u64 layer_id, u64 aruid) { | ||
| 103 | std::scoped_lock lk{m_lock}; | ||
| 104 | R_RETURN(this->OpenLayerLocked(out_producer_binder_id, layer_id, aruid)); | ||
| 105 | } | ||
| 106 | |||
| 107 | Result Container::CloseLayer(u64 layer_id) { | ||
| 108 | std::scoped_lock lk{m_lock}; | ||
| 109 | R_RETURN(this->CloseLayerLocked(layer_id)); | ||
| 110 | } | ||
| 111 | |||
| 112 | Result Container::SetLayerVisibility(u64 layer_id, bool visible) { | ||
| 113 | std::scoped_lock lk{m_lock}; | ||
| 114 | |||
| 115 | auto* const layer = m_layers.GetLayerById(layer_id); | ||
| 116 | R_UNLESS(layer != nullptr, VI::ResultNotFound); | ||
| 117 | |||
| 118 | m_surface_flinger->SetLayerVisibility(layer->GetConsumerBinderId(), visible); | ||
| 119 | R_SUCCEED(); | ||
| 120 | } | ||
| 121 | |||
| 122 | Result Container::SetLayerBlending(u64 layer_id, bool enabled) { | ||
| 123 | std::scoped_lock lk{m_lock}; | ||
| 124 | |||
| 125 | auto* const layer = m_layers.GetLayerById(layer_id); | ||
| 126 | R_UNLESS(layer != nullptr, VI::ResultNotFound); | ||
| 127 | |||
| 128 | m_surface_flinger->SetLayerBlending(layer->GetConsumerBinderId(), | ||
| 129 | enabled ? Nvnflinger::LayerBlending::Coverage | ||
| 130 | : Nvnflinger::LayerBlending::None); | ||
| 131 | R_SUCCEED(); | ||
| 132 | } | ||
| 133 | |||
| 134 | void Container::LinkVsyncEvent(u64 display_id, Event* event) { | ||
| 135 | std::scoped_lock lk{m_lock}; | ||
| 136 | m_conductor->LinkVsyncEvent(display_id, event); | ||
| 137 | } | ||
| 138 | |||
| 139 | void Container::UnlinkVsyncEvent(u64 display_id, Event* event) { | ||
| 140 | std::scoped_lock lk{m_lock}; | ||
| 141 | m_conductor->UnlinkVsyncEvent(display_id, event); | ||
| 142 | } | ||
| 143 | |||
| 144 | Result Container::CreateStrayLayer(s32* out_producer_binder_id, u64* out_layer_id, u64 display_id) { | ||
| 145 | std::scoped_lock lk{m_lock}; | ||
| 146 | R_TRY(this->CreateLayerLocked(out_layer_id, display_id, {})); | ||
| 147 | R_RETURN(this->OpenLayerLocked(out_producer_binder_id, *out_layer_id, {})); | ||
| 148 | } | ||
| 149 | |||
| 150 | Result Container::DestroyStrayLayer(u64 layer_id) { | ||
| 151 | std::scoped_lock lk{m_lock}; | ||
| 152 | R_TRY(this->CloseLayerLocked(layer_id)); | ||
| 153 | R_RETURN(this->DestroyLayerLocked(layer_id)); | ||
| 154 | } | ||
| 155 | |||
| 156 | Result Container::CreateLayerLocked(u64* out_layer_id, u64 display_id, u64 owner_aruid) { | ||
| 157 | auto* const display = m_displays.GetDisplayById(display_id); | ||
| 158 | R_UNLESS(display != nullptr, VI::ResultNotFound); | ||
| 159 | |||
| 160 | s32 consumer_binder_id, producer_binder_id; | ||
| 161 | m_surface_flinger->CreateBufferQueue(&consumer_binder_id, &producer_binder_id); | ||
| 162 | |||
| 163 | auto* const layer = | ||
| 164 | m_layers.CreateLayer(owner_aruid, display, consumer_binder_id, producer_binder_id); | ||
| 165 | R_UNLESS(layer != nullptr, VI::ResultNotFound); | ||
| 166 | |||
| 167 | m_surface_flinger->CreateLayer(consumer_binder_id); | ||
| 168 | |||
| 169 | *out_layer_id = layer->GetId(); | ||
| 170 | R_SUCCEED(); | ||
| 171 | } | ||
| 172 | |||
| 173 | Result Container::DestroyLayerLocked(u64 layer_id) { | ||
| 174 | auto* const layer = m_layers.GetLayerById(layer_id); | ||
| 175 | R_UNLESS(layer != nullptr, VI::ResultNotFound); | ||
| 176 | |||
| 177 | m_surface_flinger->DestroyLayer(layer->GetConsumerBinderId()); | ||
| 178 | m_surface_flinger->DestroyBufferQueue(layer->GetConsumerBinderId(), | ||
| 179 | layer->GetProducerBinderId()); | ||
| 180 | m_layers.DestroyLayer(layer_id); | ||
| 181 | |||
| 182 | R_SUCCEED(); | ||
| 183 | } | ||
| 184 | |||
| 185 | Result Container::OpenLayerLocked(s32* out_producer_binder_id, u64 layer_id, u64 aruid) { | ||
| 186 | R_UNLESS(!m_is_shut_down, VI::ResultOperationFailed); | ||
| 187 | |||
| 188 | auto* const layer = m_layers.GetLayerById(layer_id); | ||
| 189 | R_UNLESS(layer != nullptr, VI::ResultNotFound); | ||
| 190 | R_UNLESS(!layer->IsOpen(), VI::ResultOperationFailed); | ||
| 191 | R_UNLESS(layer->GetOwnerAruid() == aruid, VI::ResultPermissionDenied); | ||
| 192 | |||
| 193 | layer->Open(); | ||
| 194 | |||
| 195 | if (auto* display = layer->GetDisplay(); display != nullptr) { | ||
| 196 | m_surface_flinger->AddLayerToDisplayStack(display->GetId(), layer->GetConsumerBinderId()); | ||
| 197 | } | ||
| 198 | |||
| 199 | *out_producer_binder_id = layer->GetProducerBinderId(); | ||
| 200 | |||
| 201 | R_SUCCEED(); | ||
| 202 | } | ||
| 203 | |||
| 204 | Result Container::CloseLayerLocked(u64 layer_id) { | ||
| 205 | auto* const layer = m_layers.GetLayerById(layer_id); | ||
| 206 | R_UNLESS(layer != nullptr, VI::ResultNotFound); | ||
| 207 | R_UNLESS(layer->IsOpen(), VI::ResultOperationFailed); | ||
| 208 | |||
| 209 | if (auto* display = layer->GetDisplay(); display != nullptr) { | ||
| 210 | m_surface_flinger->RemoveLayerFromDisplayStack(display->GetId(), | ||
| 211 | layer->GetConsumerBinderId()); | ||
| 212 | } | ||
| 213 | |||
| 214 | layer->Close(); | ||
| 215 | |||
| 216 | R_SUCCEED(); | ||
| 217 | } | ||
| 218 | |||
| 219 | bool Container::ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, | ||
| 220 | u64 display_id) { | ||
| 221 | std::scoped_lock lk{m_lock}; | ||
| 222 | return m_surface_flinger->ComposeDisplay(out_swap_interval, out_compose_speed_scale, | ||
| 223 | display_id); | ||
| 224 | } | ||
| 225 | |||
| 226 | } // namespace Service::VI | ||
diff --git a/src/core/hle/service/vi/container.h b/src/core/hle/service/vi/container.h new file mode 100644 index 000000000..5eac4d77d --- /dev/null +++ b/src/core/hle/service/vi/container.h | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <memory> | ||
| 7 | #include <mutex> | ||
| 8 | #include <optional> | ||
| 9 | |||
| 10 | #include "core/hle/service/vi/conductor.h" | ||
| 11 | #include "core/hle/service/vi/display_list.h" | ||
| 12 | #include "core/hle/service/vi/layer_list.h" | ||
| 13 | #include "core/hle/service/vi/shared_buffer_manager.h" | ||
| 14 | |||
| 15 | union Result; | ||
| 16 | |||
| 17 | namespace Service::android { | ||
| 18 | class BufferQueueProducer; | ||
| 19 | } | ||
| 20 | |||
| 21 | namespace Service::Nvnflinger { | ||
| 22 | class IHOSBinderDriver; | ||
| 23 | class SurfaceFlinger; | ||
| 24 | } // namespace Service::Nvnflinger | ||
| 25 | |||
| 26 | namespace Service { | ||
| 27 | class Event; | ||
| 28 | } | ||
| 29 | |||
| 30 | namespace Service::VI { | ||
| 31 | |||
| 32 | class SharedBufferManager; | ||
| 33 | |||
| 34 | class Container { | ||
| 35 | public: | ||
| 36 | explicit Container(Core::System& system); | ||
| 37 | ~Container(); | ||
| 38 | |||
| 39 | void OnTerminate(); | ||
| 40 | |||
| 41 | SharedBufferManager* GetSharedBufferManager(); | ||
| 42 | |||
| 43 | Result GetBinderDriver(std::shared_ptr<Nvnflinger::IHOSBinderDriver>* out_binder_driver); | ||
| 44 | Result GetLayerProducerHandle(std::shared_ptr<android::BufferQueueProducer>* out_producer, | ||
| 45 | u64 layer_id); | ||
| 46 | |||
| 47 | Result OpenDisplay(u64* out_display_id, const DisplayName& display_name); | ||
| 48 | Result CloseDisplay(u64 display_id); | ||
| 49 | |||
| 50 | // Managed layers are created by the interaction between am and ommdisp | ||
| 51 | // on behalf of an applet. Their lifetime ends with the lifetime of the | ||
| 52 | // applet's ISelfController. | ||
| 53 | Result CreateManagedLayer(u64* out_layer_id, u64 display_id, u64 owner_aruid); | ||
| 54 | Result DestroyManagedLayer(u64 layer_id); | ||
| 55 | Result OpenLayer(s32* out_producer_binder_id, u64 layer_id, u64 aruid); | ||
| 56 | Result CloseLayer(u64 layer_id); | ||
| 57 | |||
| 58 | // Stray layers are created by non-applet sysmodules. Their lifetime ends | ||
| 59 | // with the lifetime of the IApplicationDisplayService which created them. | ||
| 60 | Result CreateStrayLayer(s32* out_producer_binder_id, u64* out_layer_id, u64 display_id); | ||
| 61 | Result DestroyStrayLayer(u64 layer_id); | ||
| 62 | |||
| 63 | Result SetLayerVisibility(u64 layer_id, bool visible); | ||
| 64 | Result SetLayerBlending(u64 layer_id, bool enabled); | ||
| 65 | |||
| 66 | void LinkVsyncEvent(u64 display_id, Event* event); | ||
| 67 | void UnlinkVsyncEvent(u64 display_id, Event* event); | ||
| 68 | |||
| 69 | private: | ||
| 70 | Result CreateLayerLocked(u64* out_layer_id, u64 display_id, u64 owner_aruid); | ||
| 71 | Result DestroyLayerLocked(u64 layer_id); | ||
| 72 | Result OpenLayerLocked(s32* out_producer_binder_id, u64 layer_id, u64 aruid); | ||
| 73 | Result CloseLayerLocked(u64 layer_id); | ||
| 74 | |||
| 75 | public: | ||
| 76 | bool ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id); | ||
| 77 | |||
| 78 | private: | ||
| 79 | std::mutex m_lock{}; | ||
| 80 | DisplayList m_displays{}; | ||
| 81 | LayerList m_layers{}; | ||
| 82 | std::shared_ptr<Nvnflinger::IHOSBinderDriver> m_binder_driver{}; | ||
| 83 | std::shared_ptr<Nvnflinger::SurfaceFlinger> m_surface_flinger{}; | ||
| 84 | std::optional<SharedBufferManager> m_shared_buffer_manager{}; | ||
| 85 | std::optional<Conductor> m_conductor{}; | ||
| 86 | bool m_is_shut_down{}; | ||
| 87 | }; | ||
| 88 | |||
| 89 | } // namespace Service::VI | ||
diff --git a/src/core/hle/service/vi/display.h b/src/core/hle/service/vi/display.h new file mode 100644 index 000000000..fceda75e3 --- /dev/null +++ b/src/core/hle/service/vi/display.h | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/vi/vi_types.h" | ||
| 7 | |||
| 8 | namespace Service::VI { | ||
| 9 | |||
| 10 | class Display { | ||
| 11 | public: | ||
| 12 | constexpr Display() = default; | ||
| 13 | |||
| 14 | void Initialize(u64 id, const DisplayName& display_name) { | ||
| 15 | m_id = id; | ||
| 16 | m_display_name = display_name; | ||
| 17 | m_is_initialized = true; | ||
| 18 | } | ||
| 19 | |||
| 20 | void Finalize() { | ||
| 21 | m_id = {}; | ||
| 22 | m_display_name = {}; | ||
| 23 | m_is_initialized = {}; | ||
| 24 | } | ||
| 25 | |||
| 26 | u64 GetId() const { | ||
| 27 | return m_id; | ||
| 28 | } | ||
| 29 | |||
| 30 | const DisplayName& GetDisplayName() const { | ||
| 31 | return m_display_name; | ||
| 32 | } | ||
| 33 | |||
| 34 | bool IsInitialized() const { | ||
| 35 | return m_is_initialized; | ||
| 36 | } | ||
| 37 | |||
| 38 | private: | ||
| 39 | u64 m_id{}; | ||
| 40 | DisplayName m_display_name{}; | ||
| 41 | bool m_is_initialized{}; | ||
| 42 | }; | ||
| 43 | |||
| 44 | } // namespace Service::VI | ||
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp deleted file mode 100644 index 7f2af9acc..000000000 --- a/src/core/hle/service/vi/display/vi_display.cpp +++ /dev/null | |||
| @@ -1,143 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include <algorithm> | ||
| 5 | #include <utility> | ||
| 6 | |||
| 7 | #include <fmt/format.h> | ||
| 8 | |||
| 9 | #include "common/assert.h" | ||
| 10 | #include "core/core.h" | ||
| 11 | #include "core/hle/kernel/k_event.h" | ||
| 12 | #include "core/hle/kernel/k_readable_event.h" | ||
| 13 | #include "core/hle/service/kernel_helpers.h" | ||
| 14 | #include "core/hle/service/nvdrv/core/container.h" | ||
| 15 | #include "core/hle/service/nvnflinger/buffer_item_consumer.h" | ||
| 16 | #include "core/hle/service/nvnflinger/buffer_queue_consumer.h" | ||
| 17 | #include "core/hle/service/nvnflinger/buffer_queue_core.h" | ||
| 18 | #include "core/hle/service/nvnflinger/buffer_queue_producer.h" | ||
| 19 | #include "core/hle/service/nvnflinger/hardware_composer.h" | ||
| 20 | #include "core/hle/service/nvnflinger/hos_binder_driver_server.h" | ||
| 21 | #include "core/hle/service/vi/display/vi_display.h" | ||
| 22 | #include "core/hle/service/vi/layer/vi_layer.h" | ||
| 23 | #include "core/hle/service/vi/vi_results.h" | ||
| 24 | |||
| 25 | namespace Service::VI { | ||
| 26 | |||
| 27 | struct BufferQueue { | ||
| 28 | std::shared_ptr<android::BufferQueueCore> core; | ||
| 29 | std::unique_ptr<android::BufferQueueProducer> producer; | ||
| 30 | std::unique_ptr<android::BufferQueueConsumer> consumer; | ||
| 31 | }; | ||
| 32 | |||
| 33 | static BufferQueue CreateBufferQueue(KernelHelpers::ServiceContext& service_context, | ||
| 34 | Service::Nvidia::NvCore::NvMap& nvmap) { | ||
| 35 | auto buffer_queue_core = std::make_shared<android::BufferQueueCore>(); | ||
| 36 | return { | ||
| 37 | buffer_queue_core, | ||
| 38 | std::make_unique<android::BufferQueueProducer>(service_context, buffer_queue_core, nvmap), | ||
| 39 | std::make_unique<android::BufferQueueConsumer>(buffer_queue_core)}; | ||
| 40 | } | ||
| 41 | |||
| 42 | Display::Display(u64 id, std::string name_, | ||
| 43 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server_, | ||
| 44 | KernelHelpers::ServiceContext& service_context_, Core::System& system_) | ||
| 45 | : display_id{id}, name{std::move(name_)}, hos_binder_driver_server{hos_binder_driver_server_}, | ||
| 46 | service_context{service_context_} { | ||
| 47 | hardware_composer = std::make_unique<Nvnflinger::HardwareComposer>(); | ||
| 48 | vsync_event = service_context.CreateEvent(fmt::format("Display VSync Event {}", id)); | ||
| 49 | } | ||
| 50 | |||
| 51 | Display::~Display() { | ||
| 52 | service_context.CloseEvent(vsync_event); | ||
| 53 | } | ||
| 54 | |||
| 55 | Layer& Display::GetLayer(std::size_t index) { | ||
| 56 | size_t i = 0; | ||
| 57 | for (auto& layer : layers) { | ||
| 58 | if (!layer->IsOpen() || !layer->IsVisible()) { | ||
| 59 | continue; | ||
| 60 | } | ||
| 61 | |||
| 62 | if (i == index) { | ||
| 63 | return *layer; | ||
| 64 | } | ||
| 65 | |||
| 66 | i++; | ||
| 67 | } | ||
| 68 | |||
| 69 | UNREACHABLE(); | ||
| 70 | } | ||
| 71 | |||
| 72 | size_t Display::GetNumLayers() const { | ||
| 73 | return std::ranges::count_if(layers, [](auto& l) { return l->IsOpen() && l->IsVisible(); }); | ||
| 74 | } | ||
| 75 | |||
| 76 | Kernel::KReadableEvent* Display::GetVSyncEvent() { | ||
| 77 | return &vsync_event->GetReadableEvent(); | ||
| 78 | } | ||
| 79 | |||
| 80 | void Display::SignalVSyncEvent() { | ||
| 81 | vsync_event->Signal(); | ||
| 82 | } | ||
| 83 | |||
| 84 | void Display::CreateLayer(u64 layer_id, u32 binder_id, | ||
| 85 | Service::Nvidia::NvCore::Container& nv_core) { | ||
| 86 | auto [core, producer, consumer] = CreateBufferQueue(service_context, nv_core.GetNvMapFile()); | ||
| 87 | |||
| 88 | auto buffer_item_consumer = std::make_shared<android::BufferItemConsumer>(std::move(consumer)); | ||
| 89 | buffer_item_consumer->Connect(false); | ||
| 90 | |||
| 91 | layers.emplace_back(std::make_unique<Layer>(layer_id, binder_id, *core, *producer, | ||
| 92 | std::move(buffer_item_consumer))); | ||
| 93 | |||
| 94 | if (is_abandoned) { | ||
| 95 | this->FindLayer(layer_id)->GetConsumer().Abandon(); | ||
| 96 | } | ||
| 97 | |||
| 98 | hos_binder_driver_server.RegisterProducer(std::move(producer)); | ||
| 99 | } | ||
| 100 | |||
| 101 | void Display::DestroyLayer(u64 layer_id) { | ||
| 102 | if (auto* layer = this->FindLayer(layer_id); layer != nullptr) { | ||
| 103 | layer->GetConsumer().Abandon(); | ||
| 104 | } | ||
| 105 | |||
| 106 | std::erase_if(layers, | ||
| 107 | [layer_id](const auto& layer) { return layer->GetLayerId() == layer_id; }); | ||
| 108 | } | ||
| 109 | |||
| 110 | void Display::Abandon() { | ||
| 111 | for (auto& layer : layers) { | ||
| 112 | layer->GetConsumer().Abandon(); | ||
| 113 | } | ||
| 114 | is_abandoned = true; | ||
| 115 | } | ||
| 116 | |||
| 117 | Layer* Display::FindLayer(u64 layer_id) { | ||
| 118 | const auto itr = | ||
| 119 | std::find_if(layers.begin(), layers.end(), [layer_id](const std::unique_ptr<Layer>& layer) { | ||
| 120 | return layer->GetLayerId() == layer_id; | ||
| 121 | }); | ||
| 122 | |||
| 123 | if (itr == layers.end()) { | ||
| 124 | return nullptr; | ||
| 125 | } | ||
| 126 | |||
| 127 | return itr->get(); | ||
| 128 | } | ||
| 129 | |||
| 130 | const Layer* Display::FindLayer(u64 layer_id) const { | ||
| 131 | const auto itr = | ||
| 132 | std::find_if(layers.begin(), layers.end(), [layer_id](const std::unique_ptr<Layer>& layer) { | ||
| 133 | return layer->GetLayerId() == layer_id; | ||
| 134 | }); | ||
| 135 | |||
| 136 | if (itr == layers.end()) { | ||
| 137 | return nullptr; | ||
| 138 | } | ||
| 139 | |||
| 140 | return itr->get(); | ||
| 141 | } | ||
| 142 | |||
| 143 | } // namespace Service::VI | ||
diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h deleted file mode 100644 index 220292cff..000000000 --- a/src/core/hle/service/vi/display/vi_display.h +++ /dev/null | |||
| @@ -1,143 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <memory> | ||
| 7 | #include <string> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include "common/common_funcs.h" | ||
| 11 | #include "common/common_types.h" | ||
| 12 | #include "core/hle/result.h" | ||
| 13 | |||
| 14 | namespace Core { | ||
| 15 | class System; | ||
| 16 | } | ||
| 17 | |||
| 18 | namespace Kernel { | ||
| 19 | class KEvent; | ||
| 20 | class KReadableEvent; | ||
| 21 | } // namespace Kernel | ||
| 22 | |||
| 23 | namespace Service::android { | ||
| 24 | class BufferQueueProducer; | ||
| 25 | } | ||
| 26 | |||
| 27 | namespace Service::KernelHelpers { | ||
| 28 | class ServiceContext; | ||
| 29 | } | ||
| 30 | |||
| 31 | namespace Service::Nvnflinger { | ||
| 32 | class HardwareComposer; | ||
| 33 | class HosBinderDriverServer; | ||
| 34 | } // namespace Service::Nvnflinger | ||
| 35 | |||
| 36 | namespace Service::Nvidia::NvCore { | ||
| 37 | class Container; | ||
| 38 | class NvMap; | ||
| 39 | } // namespace Service::Nvidia::NvCore | ||
| 40 | |||
| 41 | namespace Service::VI { | ||
| 42 | |||
| 43 | class Layer; | ||
| 44 | |||
| 45 | /// Represents a single display type | ||
| 46 | class Display { | ||
| 47 | public: | ||
| 48 | YUZU_NON_COPYABLE(Display); | ||
| 49 | YUZU_NON_MOVEABLE(Display); | ||
| 50 | |||
| 51 | /// Constructs a display with a given unique ID and name. | ||
| 52 | /// | ||
| 53 | /// @param id The unique ID for this display. | ||
| 54 | /// @param hos_binder_driver_server_ Nvnflinger HOSBinderDriver server instance. | ||
| 55 | /// @param service_context_ The ServiceContext for the owning service. | ||
| 56 | /// @param name_ The name for this display. | ||
| 57 | /// @param system_ The global system instance. | ||
| 58 | /// | ||
| 59 | Display(u64 id, std::string name_, Nvnflinger::HosBinderDriverServer& hos_binder_driver_server_, | ||
| 60 | KernelHelpers::ServiceContext& service_context_, Core::System& system_); | ||
| 61 | ~Display(); | ||
| 62 | |||
| 63 | /// Gets the unique ID assigned to this display. | ||
| 64 | u64 GetID() const { | ||
| 65 | return display_id; | ||
| 66 | } | ||
| 67 | |||
| 68 | /// Gets the name of this display | ||
| 69 | const std::string& GetName() const { | ||
| 70 | return name; | ||
| 71 | } | ||
| 72 | |||
| 73 | /// Whether or not this display has any layers added to it. | ||
| 74 | bool HasLayers() const { | ||
| 75 | return GetNumLayers() > 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | /// Gets a layer for this display based off an index. | ||
| 79 | Layer& GetLayer(std::size_t index); | ||
| 80 | |||
| 81 | std::size_t GetNumLayers() const; | ||
| 82 | |||
| 83 | /// Gets the internal vsync event. | ||
| 84 | Kernel::KReadableEvent* GetVSyncEvent(); | ||
| 85 | |||
| 86 | /// Signals the internal vsync event. | ||
| 87 | void SignalVSyncEvent(); | ||
| 88 | |||
| 89 | /// Creates and adds a layer to this display with the given ID. | ||
| 90 | /// | ||
| 91 | /// @param layer_id The ID to assign to the created layer. | ||
| 92 | /// @param binder_id The ID assigned to the buffer queue. | ||
| 93 | /// | ||
| 94 | void CreateLayer(u64 layer_id, u32 binder_id, Service::Nvidia::NvCore::Container& core); | ||
| 95 | |||
| 96 | /// Removes a layer from this display with the given ID. | ||
| 97 | /// | ||
| 98 | /// @param layer_id The ID assigned to the layer to destroy. | ||
| 99 | /// | ||
| 100 | void DestroyLayer(u64 layer_id); | ||
| 101 | |||
| 102 | /// Resets the display for a new connection. | ||
| 103 | void Reset() { | ||
| 104 | layers.clear(); | ||
| 105 | } | ||
| 106 | |||
| 107 | void Abandon(); | ||
| 108 | |||
| 109 | /// Attempts to find a layer with the given ID. | ||
| 110 | /// | ||
| 111 | /// @param layer_id The layer ID. | ||
| 112 | /// | ||
| 113 | /// @returns If found, the Layer instance with the given ID. | ||
| 114 | /// If not found, then nullptr is returned. | ||
| 115 | /// | ||
| 116 | Layer* FindLayer(u64 layer_id); | ||
| 117 | |||
| 118 | /// Attempts to find a layer with the given ID. | ||
| 119 | /// | ||
| 120 | /// @param layer_id The layer ID. | ||
| 121 | /// | ||
| 122 | /// @returns If found, the Layer instance with the given ID. | ||
| 123 | /// If not found, then nullptr is returned. | ||
| 124 | /// | ||
| 125 | const Layer* FindLayer(u64 layer_id) const; | ||
| 126 | |||
| 127 | Nvnflinger::HardwareComposer& GetComposer() const { | ||
| 128 | return *hardware_composer; | ||
| 129 | } | ||
| 130 | |||
| 131 | private: | ||
| 132 | u64 display_id; | ||
| 133 | std::string name; | ||
| 134 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server; | ||
| 135 | KernelHelpers::ServiceContext& service_context; | ||
| 136 | |||
| 137 | std::vector<std::unique_ptr<Layer>> layers; | ||
| 138 | std::unique_ptr<Nvnflinger::HardwareComposer> hardware_composer; | ||
| 139 | Kernel::KEvent* vsync_event{}; | ||
| 140 | bool is_abandoned{}; | ||
| 141 | }; | ||
| 142 | |||
| 143 | } // namespace Service::VI | ||
diff --git a/src/core/hle/service/vi/display_list.h b/src/core/hle/service/vi/display_list.h new file mode 100644 index 000000000..f710ac472 --- /dev/null +++ b/src/core/hle/service/vi/display_list.h | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <cstring> | ||
| 7 | |||
| 8 | #include "core/hle/service/vi/display.h" | ||
| 9 | |||
| 10 | namespace Service::VI { | ||
| 11 | |||
| 12 | class DisplayList { | ||
| 13 | public: | ||
| 14 | constexpr DisplayList() = default; | ||
| 15 | |||
| 16 | bool CreateDisplay(const DisplayName& name) { | ||
| 17 | Display* const display = this->GetFreeDisplay(); | ||
| 18 | if (!display) { | ||
| 19 | return false; | ||
| 20 | } | ||
| 21 | |||
| 22 | display->Initialize(m_next_id++, name); | ||
| 23 | return true; | ||
| 24 | } | ||
| 25 | |||
| 26 | bool DestroyDisplay(u64 display_id) { | ||
| 27 | Display* display = this->GetDisplayById(display_id); | ||
| 28 | if (!display) { | ||
| 29 | return false; | ||
| 30 | } | ||
| 31 | |||
| 32 | display->Finalize(); | ||
| 33 | return true; | ||
| 34 | } | ||
| 35 | |||
| 36 | Display* GetDisplayByName(const DisplayName& name) { | ||
| 37 | for (auto& display : m_displays) { | ||
| 38 | if (display.IsInitialized() && | ||
| 39 | std::strncmp(name.data(), display.GetDisplayName().data(), sizeof(DisplayName)) == | ||
| 40 | 0) { | ||
| 41 | return &display; | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | return nullptr; | ||
| 46 | } | ||
| 47 | |||
| 48 | Display* GetDisplayById(u64 display_id) { | ||
| 49 | for (auto& display : m_displays) { | ||
| 50 | if (display.IsInitialized() && display.GetId() == display_id) { | ||
| 51 | return &display; | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | return nullptr; | ||
| 56 | } | ||
| 57 | |||
| 58 | template <typename F> | ||
| 59 | void ForEachDisplay(F&& cb) { | ||
| 60 | for (auto& display : m_displays) { | ||
| 61 | if (display.IsInitialized()) { | ||
| 62 | cb(display); | ||
| 63 | } | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | private: | ||
| 68 | Display* GetFreeDisplay() { | ||
| 69 | for (auto& display : m_displays) { | ||
| 70 | if (!display.IsInitialized()) { | ||
| 71 | return &display; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | return nullptr; | ||
| 76 | } | ||
| 77 | |||
| 78 | private: | ||
| 79 | std::array<Display, 8> m_displays{}; | ||
| 80 | u64 m_next_id{}; | ||
| 81 | }; | ||
| 82 | |||
| 83 | } // namespace Service::VI | ||
diff --git a/src/core/hle/service/vi/layer.h b/src/core/hle/service/vi/layer.h new file mode 100644 index 000000000..e4c9c9864 --- /dev/null +++ b/src/core/hle/service/vi/layer.h | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/common_types.h" | ||
| 7 | |||
| 8 | namespace Service::VI { | ||
| 9 | |||
| 10 | class Display; | ||
| 11 | |||
| 12 | class Layer { | ||
| 13 | public: | ||
| 14 | constexpr Layer() = default; | ||
| 15 | |||
| 16 | void Initialize(u64 id, u64 owner_aruid, Display* display, s32 consumer_binder_id, | ||
| 17 | s32 producer_binder_id) { | ||
| 18 | m_id = id; | ||
| 19 | m_owner_aruid = owner_aruid; | ||
| 20 | m_display = display; | ||
| 21 | m_consumer_binder_id = consumer_binder_id; | ||
| 22 | m_producer_binder_id = producer_binder_id; | ||
| 23 | m_is_initialized = true; | ||
| 24 | } | ||
| 25 | |||
| 26 | void Finalize() { | ||
| 27 | m_id = {}; | ||
| 28 | m_owner_aruid = {}; | ||
| 29 | m_display = {}; | ||
| 30 | m_consumer_binder_id = {}; | ||
| 31 | m_producer_binder_id = {}; | ||
| 32 | m_is_initialized = {}; | ||
| 33 | } | ||
| 34 | |||
| 35 | void Open() { | ||
| 36 | m_is_open = true; | ||
| 37 | } | ||
| 38 | |||
| 39 | void Close() { | ||
| 40 | m_is_open = false; | ||
| 41 | } | ||
| 42 | |||
| 43 | u64 GetId() const { | ||
| 44 | return m_id; | ||
| 45 | } | ||
| 46 | |||
| 47 | u64 GetOwnerAruid() const { | ||
| 48 | return m_owner_aruid; | ||
| 49 | } | ||
| 50 | |||
| 51 | Display* GetDisplay() const { | ||
| 52 | return m_display; | ||
| 53 | } | ||
| 54 | |||
| 55 | s32 GetConsumerBinderId() const { | ||
| 56 | return m_consumer_binder_id; | ||
| 57 | } | ||
| 58 | |||
| 59 | s32 GetProducerBinderId() const { | ||
| 60 | return m_producer_binder_id; | ||
| 61 | } | ||
| 62 | |||
| 63 | bool IsInitialized() const { | ||
| 64 | return m_is_initialized; | ||
| 65 | } | ||
| 66 | |||
| 67 | bool IsOpen() const { | ||
| 68 | return m_is_open; | ||
| 69 | } | ||
| 70 | |||
| 71 | private: | ||
| 72 | u64 m_id{}; | ||
| 73 | u64 m_owner_aruid{}; | ||
| 74 | Display* m_display{}; | ||
| 75 | s32 m_consumer_binder_id{}; | ||
| 76 | s32 m_producer_binder_id{}; | ||
| 77 | bool m_is_initialized{}; | ||
| 78 | bool m_is_open{}; | ||
| 79 | }; | ||
| 80 | |||
| 81 | } // namespace Service::VI | ||
diff --git a/src/core/hle/service/vi/layer/vi_layer.cpp b/src/core/hle/service/vi/layer/vi_layer.cpp deleted file mode 100644 index eca35d82a..000000000 --- a/src/core/hle/service/vi/layer/vi_layer.cpp +++ /dev/null | |||
| @@ -1,18 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/nvnflinger/hwc_layer.h" | ||
| 5 | #include "core/hle/service/vi/layer/vi_layer.h" | ||
| 6 | |||
| 7 | namespace Service::VI { | ||
| 8 | |||
| 9 | Layer::Layer(u64 layer_id_, u32 binder_id_, android::BufferQueueCore& core_, | ||
| 10 | android::BufferQueueProducer& binder_, | ||
| 11 | std::shared_ptr<android::BufferItemConsumer>&& consumer_) | ||
| 12 | : layer_id{layer_id_}, binder_id{binder_id_}, core{core_}, binder{binder_}, consumer{std::move( | ||
| 13 | consumer_)}, | ||
| 14 | blending{Nvnflinger::LayerBlending::None}, open{false}, visible{true} {} | ||
| 15 | |||
| 16 | Layer::~Layer() = default; | ||
| 17 | |||
| 18 | } // namespace Service::VI | ||
diff --git a/src/core/hle/service/vi/layer/vi_layer.h b/src/core/hle/service/vi/layer/vi_layer.h deleted file mode 100644 index 14e229903..000000000 --- a/src/core/hle/service/vi/layer/vi_layer.h +++ /dev/null | |||
| @@ -1,118 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <memory> | ||
| 7 | #include <utility> | ||
| 8 | |||
| 9 | #include "common/common_types.h" | ||
| 10 | |||
| 11 | namespace Service::android { | ||
| 12 | class BufferItemConsumer; | ||
| 13 | class BufferQueueCore; | ||
| 14 | class BufferQueueProducer; | ||
| 15 | } // namespace Service::android | ||
| 16 | |||
| 17 | namespace Service::Nvnflinger { | ||
| 18 | enum class LayerBlending : u32; | ||
| 19 | } | ||
| 20 | |||
| 21 | namespace Service::VI { | ||
| 22 | |||
| 23 | /// Represents a single display layer. | ||
| 24 | class Layer { | ||
| 25 | public: | ||
| 26 | /// Constructs a layer with a given ID and buffer queue. | ||
| 27 | /// | ||
| 28 | /// @param layer_id_ The ID to assign to this layer. | ||
| 29 | /// @param binder_id_ The binder ID to assign to this layer. | ||
| 30 | /// @param binder_ The buffer producer queue for this layer to use. | ||
| 31 | /// | ||
| 32 | Layer(u64 layer_id_, u32 binder_id_, android::BufferQueueCore& core_, | ||
| 33 | android::BufferQueueProducer& binder_, | ||
| 34 | std::shared_ptr<android::BufferItemConsumer>&& consumer_); | ||
| 35 | ~Layer(); | ||
| 36 | |||
| 37 | Layer(const Layer&) = delete; | ||
| 38 | Layer& operator=(const Layer&) = delete; | ||
| 39 | |||
| 40 | Layer(Layer&&) = default; | ||
| 41 | Layer& operator=(Layer&&) = delete; | ||
| 42 | |||
| 43 | /// Gets the ID for this layer. | ||
| 44 | u64 GetLayerId() const { | ||
| 45 | return layer_id; | ||
| 46 | } | ||
| 47 | |||
| 48 | /// Gets the binder ID for this layer. | ||
| 49 | u32 GetBinderId() const { | ||
| 50 | return binder_id; | ||
| 51 | } | ||
| 52 | |||
| 53 | /// Gets a reference to the buffer queue this layer is using. | ||
| 54 | android::BufferQueueProducer& GetBufferQueue() { | ||
| 55 | return binder; | ||
| 56 | } | ||
| 57 | |||
| 58 | /// Gets a const reference to the buffer queue this layer is using. | ||
| 59 | const android::BufferQueueProducer& GetBufferQueue() const { | ||
| 60 | return binder; | ||
| 61 | } | ||
| 62 | |||
| 63 | android::BufferItemConsumer& GetConsumer() { | ||
| 64 | return *consumer; | ||
| 65 | } | ||
| 66 | |||
| 67 | const android::BufferItemConsumer& GetConsumer() const { | ||
| 68 | return *consumer; | ||
| 69 | } | ||
| 70 | |||
| 71 | android::BufferQueueCore& Core() { | ||
| 72 | return core; | ||
| 73 | } | ||
| 74 | |||
| 75 | const android::BufferQueueCore& Core() const { | ||
| 76 | return core; | ||
| 77 | } | ||
| 78 | |||
| 79 | bool IsVisible() const { | ||
| 80 | return visible; | ||
| 81 | } | ||
| 82 | |||
| 83 | void SetVisibility(bool v) { | ||
| 84 | visible = v; | ||
| 85 | } | ||
| 86 | |||
| 87 | bool IsOpen() const { | ||
| 88 | return open; | ||
| 89 | } | ||
| 90 | |||
| 91 | bool Close() { | ||
| 92 | return std::exchange(open, false); | ||
| 93 | } | ||
| 94 | |||
| 95 | bool Open() { | ||
| 96 | return !std::exchange(open, true); | ||
| 97 | } | ||
| 98 | |||
| 99 | Nvnflinger::LayerBlending GetBlending() { | ||
| 100 | return blending; | ||
| 101 | } | ||
| 102 | |||
| 103 | void SetBlending(Nvnflinger::LayerBlending b) { | ||
| 104 | blending = b; | ||
| 105 | } | ||
| 106 | |||
| 107 | private: | ||
| 108 | const u64 layer_id; | ||
| 109 | const u32 binder_id; | ||
| 110 | android::BufferQueueCore& core; | ||
| 111 | android::BufferQueueProducer& binder; | ||
| 112 | std::shared_ptr<android::BufferItemConsumer> consumer; | ||
| 113 | Service::Nvnflinger::LayerBlending blending; | ||
| 114 | bool open; | ||
| 115 | bool visible; | ||
| 116 | }; | ||
| 117 | |||
| 118 | } // namespace Service::VI | ||
diff --git a/src/core/hle/service/vi/layer_list.h b/src/core/hle/service/vi/layer_list.h new file mode 100644 index 000000000..4afca6f40 --- /dev/null +++ b/src/core/hle/service/vi/layer_list.h | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/vi/layer.h" | ||
| 7 | |||
| 8 | namespace Service::VI { | ||
| 9 | |||
| 10 | class LayerList { | ||
| 11 | public: | ||
| 12 | constexpr LayerList() = default; | ||
| 13 | |||
| 14 | Layer* CreateLayer(u64 owner_aruid, Display* display, s32 consumer_binder_id, | ||
| 15 | s32 producer_binder_id) { | ||
| 16 | Layer* const layer = GetFreeLayer(); | ||
| 17 | if (!layer) { | ||
| 18 | return nullptr; | ||
| 19 | } | ||
| 20 | |||
| 21 | layer->Initialize(++m_next_id, owner_aruid, display, consumer_binder_id, | ||
| 22 | producer_binder_id); | ||
| 23 | return layer; | ||
| 24 | } | ||
| 25 | |||
| 26 | bool DestroyLayer(u64 layer_id) { | ||
| 27 | Layer* const layer = GetLayerById(layer_id); | ||
| 28 | if (!layer) { | ||
| 29 | return false; | ||
| 30 | } | ||
| 31 | |||
| 32 | layer->Finalize(); | ||
| 33 | return true; | ||
| 34 | } | ||
| 35 | |||
| 36 | Layer* GetLayerById(u64 layer_id) { | ||
| 37 | for (auto& layer : m_layers) { | ||
| 38 | if (layer.IsInitialized() && layer.GetId() == layer_id) { | ||
| 39 | return &layer; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | return nullptr; | ||
| 44 | } | ||
| 45 | |||
| 46 | template <typename F> | ||
| 47 | void ForEachLayer(F&& cb) { | ||
| 48 | for (auto& layer : m_layers) { | ||
| 49 | if (layer.IsInitialized()) { | ||
| 50 | cb(layer); | ||
| 51 | } | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | private: | ||
| 56 | Layer* GetFreeLayer() { | ||
| 57 | for (auto& layer : m_layers) { | ||
| 58 | if (!layer.IsInitialized()) { | ||
| 59 | return &layer; | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | return nullptr; | ||
| 64 | } | ||
| 65 | |||
| 66 | private: | ||
| 67 | std::array<Layer, 8> m_layers{}; | ||
| 68 | u64 m_next_id{}; | ||
| 69 | }; | ||
| 70 | |||
| 71 | } // namespace Service::VI | ||
diff --git a/src/core/hle/service/vi/manager_display_service.cpp b/src/core/hle/service/vi/manager_display_service.cpp index 17f2f3b8f..9f856282e 100644 --- a/src/core/hle/service/vi/manager_display_service.cpp +++ b/src/core/hle/service/vi/manager_display_service.cpp | |||
| @@ -2,22 +2,21 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/cmif_serialization.h" | 4 | #include "core/hle/service/cmif_serialization.h" |
| 5 | #include "core/hle/service/nvnflinger/nvnflinger.h" | 5 | #include "core/hle/service/vi/container.h" |
| 6 | #include "core/hle/service/vi/manager_display_service.h" | 6 | #include "core/hle/service/vi/manager_display_service.h" |
| 7 | #include "core/hle/service/vi/vi_results.h" | ||
| 8 | 7 | ||
| 9 | namespace Service::VI { | 8 | namespace Service::VI { |
| 10 | 9 | ||
| 11 | IManagerDisplayService::IManagerDisplayService(Core::System& system_, | 10 | IManagerDisplayService::IManagerDisplayService(Core::System& system_, |
| 12 | Nvnflinger::Nvnflinger& nvnflinger) | 11 | std::shared_ptr<Container> container) |
| 13 | : ServiceFramework{system_, "IManagerDisplayService"}, m_nvnflinger{nvnflinger} { | 12 | : ServiceFramework{system_, "IManagerDisplayService"}, m_container{std::move(container)} { |
| 14 | // clang-format off | 13 | // clang-format off |
| 15 | static const FunctionInfo functions[] = { | 14 | static const FunctionInfo functions[] = { |
| 16 | {200, nullptr, "AllocateProcessHeapBlock"}, | 15 | {200, nullptr, "AllocateProcessHeapBlock"}, |
| 17 | {201, nullptr, "FreeProcessHeapBlock"}, | 16 | {201, nullptr, "FreeProcessHeapBlock"}, |
| 18 | {1102, nullptr, "GetDisplayResolution"}, | 17 | {1102, nullptr, "GetDisplayResolution"}, |
| 19 | {2010, C<&IManagerDisplayService::CreateManagedLayer>, "CreateManagedLayer"}, | 18 | {2010, C<&IManagerDisplayService::CreateManagedLayer>, "CreateManagedLayer"}, |
| 20 | {2011, nullptr, "DestroyManagedLayer"}, | 19 | {2011, C<&IManagerDisplayService::DestroyManagedLayer>, "DestroyManagedLayer"}, |
| 21 | {2012, nullptr, "CreateStrayLayer"}, | 20 | {2012, nullptr, "CreateStrayLayer"}, |
| 22 | {2050, nullptr, "CreateIndirectLayer"}, | 21 | {2050, nullptr, "CreateIndirectLayer"}, |
| 23 | {2051, nullptr, "DestroyIndirectLayer"}, | 22 | {2051, nullptr, "DestroyIndirectLayer"}, |
| @@ -102,19 +101,30 @@ IManagerDisplayService::IManagerDisplayService(Core::System& system_, | |||
| 102 | 101 | ||
| 103 | IManagerDisplayService::~IManagerDisplayService() = default; | 102 | IManagerDisplayService::~IManagerDisplayService() = default; |
| 104 | 103 | ||
| 105 | Result IManagerDisplayService::CreateManagedLayer(Out<u64> out_layer_id, u32 unknown, | 104 | Result IManagerDisplayService::CreateSharedLayerSession(Kernel::KProcess* owner_process, |
| 106 | u64 display_id, AppletResourceUserId aruid) { | 105 | u64* out_buffer_id, u64* out_layer_handle, |
| 107 | LOG_WARNING(Service_VI, "(STUBBED) called. unknown={}, display={}, aruid={}", unknown, | 106 | u64 display_id, bool enable_blending) { |
| 108 | display_id, aruid.pid); | 107 | R_RETURN(m_container->GetSharedBufferManager()->CreateSession( |
| 108 | owner_process, out_buffer_id, out_layer_handle, display_id, enable_blending)); | ||
| 109 | } | ||
| 109 | 110 | ||
| 110 | const auto layer_id = m_nvnflinger.CreateLayer(display_id); | 111 | void IManagerDisplayService::DestroySharedLayerSession(Kernel::KProcess* owner_process) { |
| 111 | if (!layer_id) { | 112 | m_container->GetSharedBufferManager()->DestroySession(owner_process); |
| 112 | LOG_ERROR(Service_VI, "Layer not found! display={}", display_id); | 113 | } |
| 113 | R_THROW(VI::ResultNotFound); | ||
| 114 | } | ||
| 115 | 114 | ||
| 116 | *out_layer_id = *layer_id; | 115 | Result IManagerDisplayService::SetLayerBlending(bool enabled, u64 layer_id) { |
| 117 | R_SUCCEED(); | 116 | R_RETURN(m_container->SetLayerBlending(layer_id, enabled)); |
| 117 | } | ||
| 118 | |||
| 119 | Result IManagerDisplayService::CreateManagedLayer(Out<u64> out_layer_id, u32 flags, u64 display_id, | ||
| 120 | AppletResourceUserId aruid) { | ||
| 121 | LOG_DEBUG(Service_VI, "called. flags={}, display={}, aruid={}", flags, display_id, aruid.pid); | ||
| 122 | R_RETURN(m_container->CreateManagedLayer(out_layer_id, display_id, aruid.pid)); | ||
| 123 | } | ||
| 124 | |||
| 125 | Result IManagerDisplayService::DestroyManagedLayer(u64 layer_id) { | ||
| 126 | LOG_DEBUG(Service_VI, "called. layer_id={}", layer_id); | ||
| 127 | R_RETURN(m_container->DestroyManagedLayer(layer_id)); | ||
| 118 | } | 128 | } |
| 119 | 129 | ||
| 120 | Result IManagerDisplayService::AddToLayerStack(u32 stack_id, u64 layer_id) { | 130 | Result IManagerDisplayService::AddToLayerStack(u32 stack_id, u64 layer_id) { |
| @@ -123,8 +133,8 @@ Result IManagerDisplayService::AddToLayerStack(u32 stack_id, u64 layer_id) { | |||
| 123 | } | 133 | } |
| 124 | 134 | ||
| 125 | Result IManagerDisplayService::SetLayerVisibility(bool visible, u64 layer_id) { | 135 | Result IManagerDisplayService::SetLayerVisibility(bool visible, u64 layer_id) { |
| 126 | LOG_WARNING(Service_VI, "(STUBBED) called, layer_id={}, visible={}", layer_id, visible); | 136 | LOG_DEBUG(Service_VI, "called, layer_id={}, visible={}", layer_id, visible); |
| 127 | R_SUCCEED(); | 137 | R_RETURN(m_container->SetLayerVisibility(layer_id, visible)); |
| 128 | } | 138 | } |
| 129 | 139 | ||
| 130 | } // namespace Service::VI | 140 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/manager_display_service.h b/src/core/hle/service/vi/manager_display_service.h index 60e646ee0..b1bdf7f41 100644 --- a/src/core/hle/service/vi/manager_display_service.h +++ b/src/core/hle/service/vi/manager_display_service.h | |||
| @@ -4,21 +4,34 @@ | |||
| 4 | #include "core/hle/service/cmif_types.h" | 4 | #include "core/hle/service/cmif_types.h" |
| 5 | #include "core/hle/service/service.h" | 5 | #include "core/hle/service/service.h" |
| 6 | 6 | ||
| 7 | namespace Kernel { | ||
| 8 | class KProcess; | ||
| 9 | } | ||
| 10 | |||
| 7 | namespace Service::VI { | 11 | namespace Service::VI { |
| 8 | 12 | ||
| 13 | class Container; | ||
| 14 | |||
| 9 | class IManagerDisplayService final : public ServiceFramework<IManagerDisplayService> { | 15 | class IManagerDisplayService final : public ServiceFramework<IManagerDisplayService> { |
| 10 | public: | 16 | public: |
| 11 | explicit IManagerDisplayService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger); | 17 | explicit IManagerDisplayService(Core::System& system_, std::shared_ptr<Container> container); |
| 12 | ~IManagerDisplayService() override; | 18 | ~IManagerDisplayService() override; |
| 13 | 19 | ||
| 14 | private: | 20 | Result CreateSharedLayerSession(Kernel::KProcess* owner_process, u64* out_buffer_id, |
| 15 | Result CreateManagedLayer(Out<u64> out_layer_id, u32 unknown, u64 display_id, | 21 | u64* out_layer_handle, u64 display_id, bool enable_blending); |
| 22 | void DestroySharedLayerSession(Kernel::KProcess* owner_process); | ||
| 23 | |||
| 24 | Result SetLayerBlending(bool enabled, u64 layer_id); | ||
| 25 | |||
| 26 | public: | ||
| 27 | Result CreateManagedLayer(Out<u64> out_layer_id, u32 flags, u64 display_id, | ||
| 16 | AppletResourceUserId aruid); | 28 | AppletResourceUserId aruid); |
| 29 | Result DestroyManagedLayer(u64 layer_id); | ||
| 17 | Result AddToLayerStack(u32 stack_id, u64 layer_id); | 30 | Result AddToLayerStack(u32 stack_id, u64 layer_id); |
| 18 | Result SetLayerVisibility(bool visible, u64 layer_id); | 31 | Result SetLayerVisibility(bool visible, u64 layer_id); |
| 19 | 32 | ||
| 20 | private: | 33 | private: |
| 21 | Nvnflinger::Nvnflinger& m_nvnflinger; | 34 | const std::shared_ptr<Container> m_container; |
| 22 | }; | 35 | }; |
| 23 | 36 | ||
| 24 | } // namespace Service::VI | 37 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/manager_root_service.cpp b/src/core/hle/service/vi/manager_root_service.cpp index a7eee4f04..0f16a15b4 100644 --- a/src/core/hle/service/vi/manager_root_service.cpp +++ b/src/core/hle/service/vi/manager_root_service.cpp | |||
| @@ -2,7 +2,9 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/cmif_serialization.h" | 4 | #include "core/hle/service/cmif_serialization.h" |
| 5 | #include "core/hle/service/nvnflinger/hos_binder_driver.h" | ||
| 5 | #include "core/hle/service/vi/application_display_service.h" | 6 | #include "core/hle/service/vi/application_display_service.h" |
| 7 | #include "core/hle/service/vi/container.h" | ||
| 6 | #include "core/hle/service/vi/manager_root_service.h" | 8 | #include "core/hle/service/vi/manager_root_service.h" |
| 7 | #include "core/hle/service/vi/service_creator.h" | 9 | #include "core/hle/service/vi/service_creator.h" |
| 8 | #include "core/hle/service/vi/vi.h" | 10 | #include "core/hle/service/vi/vi.h" |
| @@ -10,11 +12,9 @@ | |||
| 10 | 12 | ||
| 11 | namespace Service::VI { | 13 | namespace Service::VI { |
| 12 | 14 | ||
| 13 | IManagerRootService::IManagerRootService( | 15 | IManagerRootService::IManagerRootService(Core::System& system_, |
| 14 | Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger, | 16 | std::shared_ptr<Container> container) |
| 15 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server) | 17 | : ServiceFramework{system_, "vi:m"}, m_container{std::move(container)} { |
| 16 | : ServiceFramework{system_, "vi:m"}, m_nvnflinger{nvnflinger}, m_hos_binder_driver_server{ | ||
| 17 | hos_binder_driver_server} { | ||
| 18 | static const FunctionInfo functions[] = { | 18 | static const FunctionInfo functions[] = { |
| 19 | {2, C<&IManagerRootService::GetDisplayService>, "GetDisplayService"}, | 19 | {2, C<&IManagerRootService::GetDisplayService>, "GetDisplayService"}, |
| 20 | {3, nullptr, "GetDisplayServiceWithProxyNameExchange"}, | 20 | {3, nullptr, "GetDisplayServiceWithProxyNameExchange"}, |
| @@ -31,8 +31,8 @@ IManagerRootService::~IManagerRootService() = default; | |||
| 31 | Result IManagerRootService::GetDisplayService( | 31 | Result IManagerRootService::GetDisplayService( |
| 32 | Out<SharedPointer<IApplicationDisplayService>> out_application_display_service, Policy policy) { | 32 | Out<SharedPointer<IApplicationDisplayService>> out_application_display_service, Policy policy) { |
| 33 | LOG_DEBUG(Service_VI, "called"); | 33 | LOG_DEBUG(Service_VI, "called"); |
| 34 | R_RETURN(GetApplicationDisplayService(out_application_display_service, system, m_nvnflinger, | 34 | R_RETURN(GetApplicationDisplayService(out_application_display_service, system, m_container, |
| 35 | m_hos_binder_driver_server, Permission::Manager, policy)); | 35 | Permission::Manager, policy)); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | } // namespace Service::VI | 38 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/manager_root_service.h b/src/core/hle/service/vi/manager_root_service.h index e6cb77aeb..77cd32869 100644 --- a/src/core/hle/service/vi/manager_root_service.h +++ b/src/core/hle/service/vi/manager_root_service.h | |||
| @@ -10,29 +10,23 @@ namespace Core { | |||
| 10 | class System; | 10 | class System; |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | namespace Service::Nvnflinger { | ||
| 14 | class HosBinderDriverServer; | ||
| 15 | class Nvnflinger; | ||
| 16 | } // namespace Service::Nvnflinger | ||
| 17 | |||
| 18 | namespace Service::VI { | 13 | namespace Service::VI { |
| 19 | 14 | ||
| 15 | class Container; | ||
| 20 | class IApplicationDisplayService; | 16 | class IApplicationDisplayService; |
| 21 | enum class Policy : u32; | 17 | enum class Policy : u32; |
| 22 | 18 | ||
| 23 | class IManagerRootService final : public ServiceFramework<IManagerRootService> { | 19 | class IManagerRootService final : public ServiceFramework<IManagerRootService> { |
| 24 | public: | 20 | public: |
| 25 | explicit IManagerRootService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger, | 21 | explicit IManagerRootService(Core::System& system_, std::shared_ptr<Container> container); |
| 26 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server); | ||
| 27 | ~IManagerRootService() override; | 22 | ~IManagerRootService() override; |
| 28 | 23 | ||
| 29 | private: | ||
| 30 | Result GetDisplayService( | 24 | Result GetDisplayService( |
| 31 | Out<SharedPointer<IApplicationDisplayService>> out_application_display_service, | 25 | Out<SharedPointer<IApplicationDisplayService>> out_application_display_service, |
| 32 | Policy policy); | 26 | Policy policy); |
| 33 | 27 | ||
| 34 | Nvnflinger::Nvnflinger& m_nvnflinger; | 28 | private: |
| 35 | Nvnflinger::HosBinderDriverServer& m_hos_binder_driver_server; | 29 | const std::shared_ptr<Container> m_container; |
| 36 | }; | 30 | }; |
| 37 | 31 | ||
| 38 | } // namespace Service::VI | 32 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/service_creator.cpp b/src/core/hle/service/vi/service_creator.cpp index 1de9d61a4..2b8e5f957 100644 --- a/src/core/hle/service/vi/service_creator.cpp +++ b/src/core/hle/service/vi/service_creator.cpp | |||
| @@ -22,8 +22,7 @@ static bool IsValidServiceAccess(Permission permission, Policy policy) { | |||
| 22 | 22 | ||
| 23 | Result GetApplicationDisplayService( | 23 | Result GetApplicationDisplayService( |
| 24 | std::shared_ptr<IApplicationDisplayService>* out_application_display_service, | 24 | std::shared_ptr<IApplicationDisplayService>* out_application_display_service, |
| 25 | Core::System& system, Nvnflinger::Nvnflinger& nvnflinger, | 25 | Core::System& system, std::shared_ptr<Container> container, Permission permission, |
| 26 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server, Permission permission, | ||
| 27 | Policy policy) { | 26 | Policy policy) { |
| 28 | 27 | ||
| 29 | if (!IsValidServiceAccess(permission, policy)) { | 28 | if (!IsValidServiceAccess(permission, policy)) { |
| @@ -32,7 +31,7 @@ Result GetApplicationDisplayService( | |||
| 32 | } | 31 | } |
| 33 | 32 | ||
| 34 | *out_application_display_service = | 33 | *out_application_display_service = |
| 35 | std::make_shared<IApplicationDisplayService>(system, nvnflinger, hos_binder_driver_server); | 34 | std::make_shared<IApplicationDisplayService>(system, std::move(container)); |
| 36 | R_SUCCEED(); | 35 | R_SUCCEED(); |
| 37 | } | 36 | } |
| 38 | 37 | ||
diff --git a/src/core/hle/service/vi/service_creator.h b/src/core/hle/service/vi/service_creator.h index 8963bcd26..c6ba1797d 100644 --- a/src/core/hle/service/vi/service_creator.h +++ b/src/core/hle/service/vi/service_creator.h | |||
| @@ -11,23 +11,18 @@ namespace Core { | |||
| 11 | class System; | 11 | class System; |
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | namespace Service::Nvnflinger { | ||
| 15 | class HosBinderDriverServer; | ||
| 16 | class Nvnflinger; | ||
| 17 | } // namespace Service::Nvnflinger | ||
| 18 | |||
| 19 | union Result; | 14 | union Result; |
| 20 | 15 | ||
| 21 | namespace Service::VI { | 16 | namespace Service::VI { |
| 22 | 17 | ||
| 18 | class Container; | ||
| 23 | class IApplicationDisplayService; | 19 | class IApplicationDisplayService; |
| 24 | enum class Permission; | 20 | enum class Permission; |
| 25 | enum class Policy : u32; | 21 | enum class Policy : u32; |
| 26 | 22 | ||
| 27 | Result GetApplicationDisplayService( | 23 | Result GetApplicationDisplayService( |
| 28 | std::shared_ptr<IApplicationDisplayService>* out_application_display_service, | 24 | std::shared_ptr<IApplicationDisplayService>* out_application_display_service, |
| 29 | Core::System& system, Nvnflinger::Nvnflinger& nvnflinger, | 25 | Core::System& system, std::shared_ptr<Container> container, Permission permission, |
| 30 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server, Permission permission, | ||
| 31 | Policy policy); | 26 | Policy policy); |
| 32 | 27 | ||
| 33 | } // namespace Service::VI | 28 | } // namespace Service::VI |
diff --git a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp b/src/core/hle/service/vi/shared_buffer_manager.cpp index 90f7248a0..12cba16fa 100644 --- a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp +++ b/src/core/hle/service/vi/shared_buffer_manager.cpp | |||
| @@ -9,15 +9,15 @@ | |||
| 9 | #include "core/hle/service/nvdrv/devices/nvmap.h" | 9 | #include "core/hle/service/nvdrv/devices/nvmap.h" |
| 10 | #include "core/hle/service/nvdrv/nvdrv.h" | 10 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 11 | #include "core/hle/service/nvnflinger/buffer_queue_producer.h" | 11 | #include "core/hle/service/nvnflinger/buffer_queue_producer.h" |
| 12 | #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" | ||
| 13 | #include "core/hle/service/nvnflinger/pixel_format.h" | 12 | #include "core/hle/service/nvnflinger/pixel_format.h" |
| 14 | #include "core/hle/service/nvnflinger/ui/graphic_buffer.h" | 13 | #include "core/hle/service/nvnflinger/ui/graphic_buffer.h" |
| 15 | #include "core/hle/service/vi/layer/vi_layer.h" | 14 | #include "core/hle/service/vi/container.h" |
| 15 | #include "core/hle/service/vi/shared_buffer_manager.h" | ||
| 16 | #include "core/hle/service/vi/vi_results.h" | 16 | #include "core/hle/service/vi/vi_results.h" |
| 17 | #include "video_core/gpu.h" | 17 | #include "video_core/gpu.h" |
| 18 | #include "video_core/host1x/host1x.h" | 18 | #include "video_core/host1x/host1x.h" |
| 19 | 19 | ||
| 20 | namespace Service::Nvnflinger { | 20 | namespace Service::VI { |
| 21 | 21 | ||
| 22 | namespace { | 22 | namespace { |
| 23 | 23 | ||
| @@ -26,7 +26,6 @@ Result AllocateSharedBufferMemory(std::unique_ptr<Kernel::KPageGroup>* out_page_ | |||
| 26 | using Core::Memory::YUZU_PAGESIZE; | 26 | using Core::Memory::YUZU_PAGESIZE; |
| 27 | 27 | ||
| 28 | // Allocate memory for the system shared buffer. | 28 | // Allocate memory for the system shared buffer. |
| 29 | // FIXME: This memory belongs to vi's .data section. | ||
| 30 | auto& kernel = system.Kernel(); | 29 | auto& kernel = system.Kernel(); |
| 31 | 30 | ||
| 32 | // Hold a temporary page group reference while we try to map it. | 31 | // Hold a temporary page group reference while we try to map it. |
| @@ -204,15 +203,15 @@ void MakeGraphicBuffer(android::BufferQueueProducer& producer, u32 slot, u32 han | |||
| 204 | 203 | ||
| 205 | } // namespace | 204 | } // namespace |
| 206 | 205 | ||
| 207 | FbShareBufferManager::FbShareBufferManager(Core::System& system, Nvnflinger& flinger, | 206 | SharedBufferManager::SharedBufferManager(Core::System& system, Container& container, |
| 208 | std::shared_ptr<Nvidia::Module> nvdrv) | 207 | std::shared_ptr<Nvidia::Module> nvdrv) |
| 209 | : m_system(system), m_flinger(flinger), m_nvdrv(std::move(nvdrv)) {} | 208 | : m_system(system), m_container(container), m_nvdrv(std::move(nvdrv)) {} |
| 210 | 209 | ||
| 211 | FbShareBufferManager::~FbShareBufferManager() = default; | 210 | SharedBufferManager::~SharedBufferManager() = default; |
| 212 | 211 | ||
| 213 | Result FbShareBufferManager::Initialize(Kernel::KProcess* owner_process, u64* out_buffer_id, | 212 | Result SharedBufferManager::CreateSession(Kernel::KProcess* owner_process, u64* out_buffer_id, |
| 214 | u64* out_layer_handle, u64 display_id, | 213 | u64* out_layer_handle, u64 display_id, |
| 215 | LayerBlending blending) { | 214 | bool enable_blending) { |
| 216 | std::scoped_lock lk{m_guard}; | 215 | std::scoped_lock lk{m_guard}; |
| 217 | 216 | ||
| 218 | // Ensure we haven't already created. | 217 | // Ensure we haven't already created. |
| @@ -237,7 +236,7 @@ Result FbShareBufferManager::Initialize(Kernel::KProcess* owner_process, u64* ou | |||
| 237 | owner_process, m_system)); | 236 | owner_process, m_system)); |
| 238 | 237 | ||
| 239 | // Create new session. | 238 | // Create new session. |
| 240 | auto [it, was_emplaced] = m_sessions.emplace(aruid, FbShareSession{}); | 239 | auto [it, was_emplaced] = m_sessions.emplace(aruid, SharedBufferSession{}); |
| 241 | auto& session = it->second; | 240 | auto& session = it->second; |
| 242 | 241 | ||
| 243 | auto& container = m_nvdrv->GetContainer(); | 242 | auto& container = m_nvdrv->GetContainer(); |
| @@ -249,17 +248,18 @@ Result FbShareBufferManager::Initialize(Kernel::KProcess* owner_process, u64* ou | |||
| 249 | session.nvmap_fd, map_address, SharedBufferSize)); | 248 | session.nvmap_fd, map_address, SharedBufferSize)); |
| 250 | 249 | ||
| 251 | // Create and open a layer for the display. | 250 | // Create and open a layer for the display. |
| 252 | session.layer_id = m_flinger.CreateLayer(m_display_id, blending).value(); | 251 | s32 producer_binder_id; |
| 253 | m_flinger.OpenLayer(session.layer_id); | 252 | R_TRY(m_container.CreateStrayLayer(std::addressof(producer_binder_id), |
| 253 | std::addressof(session.layer_id), display_id)); | ||
| 254 | 254 | ||
| 255 | // Get the layer. | 255 | // Configure blending. |
| 256 | VI::Layer* layer = m_flinger.FindLayer(m_display_id, session.layer_id); | 256 | R_ASSERT(m_container.SetLayerBlending(session.layer_id, enable_blending)); |
| 257 | ASSERT(layer != nullptr); | ||
| 258 | 257 | ||
| 259 | // Get the producer and set preallocated buffers. | 258 | // Get the producer and set preallocated buffers. |
| 260 | auto& producer = layer->GetBufferQueue(); | 259 | std::shared_ptr<android::BufferQueueProducer> producer; |
| 261 | MakeGraphicBuffer(producer, 0, session.buffer_nvmap_handle); | 260 | R_TRY(m_container.GetLayerProducerHandle(std::addressof(producer), session.layer_id)); |
| 262 | MakeGraphicBuffer(producer, 1, session.buffer_nvmap_handle); | 261 | MakeGraphicBuffer(*producer, 0, session.buffer_nvmap_handle); |
| 262 | MakeGraphicBuffer(*producer, 1, session.buffer_nvmap_handle); | ||
| 263 | 263 | ||
| 264 | // Assign outputs. | 264 | // Assign outputs. |
| 265 | *out_buffer_id = m_buffer_id; | 265 | *out_buffer_id = m_buffer_id; |
| @@ -269,7 +269,7 @@ Result FbShareBufferManager::Initialize(Kernel::KProcess* owner_process, u64* ou | |||
| 269 | R_SUCCEED(); | 269 | R_SUCCEED(); |
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | void FbShareBufferManager::Finalize(Kernel::KProcess* owner_process) { | 272 | void SharedBufferManager::DestroySession(Kernel::KProcess* owner_process) { |
| 273 | std::scoped_lock lk{m_guard}; | 273 | std::scoped_lock lk{m_guard}; |
| 274 | 274 | ||
| 275 | if (m_buffer_id == 0) { | 275 | if (m_buffer_id == 0) { |
| @@ -285,7 +285,7 @@ void FbShareBufferManager::Finalize(Kernel::KProcess* owner_process) { | |||
| 285 | auto& session = it->second; | 285 | auto& session = it->second; |
| 286 | 286 | ||
| 287 | // Destroy the layer. | 287 | // Destroy the layer. |
| 288 | m_flinger.DestroyLayer(session.layer_id); | 288 | m_container.DestroyStrayLayer(session.layer_id); |
| 289 | 289 | ||
| 290 | // Close nvmap handle. | 290 | // Close nvmap handle. |
| 291 | FreeHandle(session.buffer_nvmap_handle, *m_nvdrv, session.nvmap_fd); | 291 | FreeHandle(session.buffer_nvmap_handle, *m_nvdrv, session.nvmap_fd); |
| @@ -301,11 +301,11 @@ void FbShareBufferManager::Finalize(Kernel::KProcess* owner_process) { | |||
| 301 | m_sessions.erase(it); | 301 | m_sessions.erase(it); |
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | Result FbShareBufferManager::GetSharedBufferMemoryHandleId(u64* out_buffer_size, | 304 | Result SharedBufferManager::GetSharedBufferMemoryHandleId(u64* out_buffer_size, |
| 305 | s32* out_nvmap_handle, | 305 | s32* out_nvmap_handle, |
| 306 | SharedMemoryPoolLayout* out_pool_layout, | 306 | SharedMemoryPoolLayout* out_pool_layout, |
| 307 | u64 buffer_id, | 307 | u64 buffer_id, |
| 308 | u64 applet_resource_user_id) { | 308 | u64 applet_resource_user_id) { |
| 309 | std::scoped_lock lk{m_guard}; | 309 | std::scoped_lock lk{m_guard}; |
| 310 | 310 | ||
| 311 | R_UNLESS(m_buffer_id > 0, VI::ResultNotFound); | 311 | R_UNLESS(m_buffer_id > 0, VI::ResultNotFound); |
| @@ -319,36 +319,18 @@ Result FbShareBufferManager::GetSharedBufferMemoryHandleId(u64* out_buffer_size, | |||
| 319 | R_SUCCEED(); | 319 | R_SUCCEED(); |
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | Result FbShareBufferManager::GetLayerFromId(VI::Layer** out_layer, u64 layer_id) { | 322 | Result SharedBufferManager::AcquireSharedFrameBuffer(android::Fence* out_fence, |
| 323 | // Ensure the layer id is valid. | 323 | std::array<s32, 4>& out_slot_indexes, |
| 324 | R_UNLESS(layer_id > 0, VI::ResultNotFound); | 324 | s64* out_target_slot, u64 layer_id) { |
| 325 | |||
| 326 | // Get the layer. | ||
| 327 | VI::Layer* layer = m_flinger.FindLayer(m_display_id, layer_id); | ||
| 328 | R_UNLESS(layer != nullptr, VI::ResultNotFound); | ||
| 329 | |||
| 330 | // We succeeded. | ||
| 331 | *out_layer = layer; | ||
| 332 | R_SUCCEED(); | ||
| 333 | } | ||
| 334 | |||
| 335 | Result FbShareBufferManager::AcquireSharedFrameBuffer(android::Fence* out_fence, | ||
| 336 | std::array<s32, 4>& out_slot_indexes, | ||
| 337 | s64* out_target_slot, u64 layer_id) { | ||
| 338 | std::scoped_lock lk{m_guard}; | ||
| 339 | |||
| 340 | // Get the layer. | ||
| 341 | VI::Layer* layer; | ||
| 342 | R_TRY(this->GetLayerFromId(std::addressof(layer), layer_id)); | ||
| 343 | |||
| 344 | // Get the producer. | 325 | // Get the producer. |
| 345 | auto& producer = layer->GetBufferQueue(); | 326 | std::shared_ptr<android::BufferQueueProducer> producer; |
| 327 | R_TRY(m_container.GetLayerProducerHandle(std::addressof(producer), layer_id)); | ||
| 346 | 328 | ||
| 347 | // Get the next buffer from the producer. | 329 | // Get the next buffer from the producer. |
| 348 | s32 slot; | 330 | s32 slot; |
| 349 | R_UNLESS(producer.DequeueBuffer(std::addressof(slot), out_fence, SharedBufferAsync != 0, | 331 | R_UNLESS(producer->DequeueBuffer(std::addressof(slot), out_fence, SharedBufferAsync != 0, |
| 350 | SharedBufferWidth, SharedBufferHeight, | 332 | SharedBufferWidth, SharedBufferHeight, |
| 351 | SharedBufferBlockLinearFormat, 0) == android::Status::NoError, | 333 | SharedBufferBlockLinearFormat, 0) == android::Status::NoError, |
| 352 | VI::ResultOperationFailed); | 334 | VI::ResultOperationFailed); |
| 353 | 335 | ||
| 354 | // Assign remaining outputs. | 336 | // Assign remaining outputs. |
| @@ -359,27 +341,22 @@ Result FbShareBufferManager::AcquireSharedFrameBuffer(android::Fence* out_fence, | |||
| 359 | R_SUCCEED(); | 341 | R_SUCCEED(); |
| 360 | } | 342 | } |
| 361 | 343 | ||
| 362 | Result FbShareBufferManager::PresentSharedFrameBuffer(android::Fence fence, | 344 | Result SharedBufferManager::PresentSharedFrameBuffer(android::Fence fence, |
| 363 | Common::Rectangle<s32> crop_region, | 345 | Common::Rectangle<s32> crop_region, |
| 364 | u32 transform, s32 swap_interval, | 346 | u32 transform, s32 swap_interval, u64 layer_id, |
| 365 | u64 layer_id, s64 slot) { | 347 | s64 slot) { |
| 366 | std::scoped_lock lk{m_guard}; | ||
| 367 | |||
| 368 | // Get the layer. | ||
| 369 | VI::Layer* layer; | ||
| 370 | R_TRY(this->GetLayerFromId(std::addressof(layer), layer_id)); | ||
| 371 | |||
| 372 | // Get the producer. | 348 | // Get the producer. |
| 373 | auto& producer = layer->GetBufferQueue(); | 349 | std::shared_ptr<android::BufferQueueProducer> producer; |
| 350 | R_TRY(m_container.GetLayerProducerHandle(std::addressof(producer), layer_id)); | ||
| 374 | 351 | ||
| 375 | // Request to queue the buffer. | 352 | // Request to queue the buffer. |
| 376 | std::shared_ptr<android::GraphicBuffer> buffer; | 353 | std::shared_ptr<android::GraphicBuffer> buffer; |
| 377 | R_UNLESS(producer.RequestBuffer(static_cast<s32>(slot), std::addressof(buffer)) == | 354 | R_UNLESS(producer->RequestBuffer(static_cast<s32>(slot), std::addressof(buffer)) == |
| 378 | android::Status::NoError, | 355 | android::Status::NoError, |
| 379 | VI::ResultOperationFailed); | 356 | VI::ResultOperationFailed); |
| 380 | 357 | ||
| 381 | ON_RESULT_FAILURE { | 358 | ON_RESULT_FAILURE { |
| 382 | producer.CancelBuffer(static_cast<s32>(slot), fence); | 359 | producer->CancelBuffer(static_cast<s32>(slot), fence); |
| 383 | }; | 360 | }; |
| 384 | 361 | ||
| 385 | // Queue the buffer to the producer. | 362 | // Queue the buffer to the producer. |
| @@ -389,7 +366,7 @@ Result FbShareBufferManager::PresentSharedFrameBuffer(android::Fence fence, | |||
| 389 | input.fence = fence; | 366 | input.fence = fence; |
| 390 | input.transform = static_cast<android::NativeWindowTransform>(transform); | 367 | input.transform = static_cast<android::NativeWindowTransform>(transform); |
| 391 | input.swap_interval = swap_interval; | 368 | input.swap_interval = swap_interval; |
| 392 | R_UNLESS(producer.QueueBuffer(static_cast<s32>(slot), input, std::addressof(output)) == | 369 | R_UNLESS(producer->QueueBuffer(static_cast<s32>(slot), input, std::addressof(output)) == |
| 393 | android::Status::NoError, | 370 | android::Status::NoError, |
| 394 | VI::ResultOperationFailed); | 371 | VI::ResultOperationFailed); |
| 395 | 372 | ||
| @@ -397,25 +374,32 @@ Result FbShareBufferManager::PresentSharedFrameBuffer(android::Fence fence, | |||
| 397 | R_SUCCEED(); | 374 | R_SUCCEED(); |
| 398 | } | 375 | } |
| 399 | 376 | ||
| 400 | Result FbShareBufferManager::GetSharedFrameBufferAcquirableEvent(Kernel::KReadableEvent** out_event, | 377 | Result SharedBufferManager::CancelSharedFrameBuffer(u64 layer_id, s64 slot) { |
| 401 | u64 layer_id) { | 378 | // Get the producer. |
| 402 | std::scoped_lock lk{m_guard}; | 379 | std::shared_ptr<android::BufferQueueProducer> producer; |
| 380 | R_TRY(m_container.GetLayerProducerHandle(std::addressof(producer), layer_id)); | ||
| 403 | 381 | ||
| 404 | // Get the layer. | 382 | // Cancel. |
| 405 | VI::Layer* layer; | 383 | producer->CancelBuffer(static_cast<s32>(slot), android::Fence::NoFence()); |
| 406 | R_TRY(this->GetLayerFromId(std::addressof(layer), layer_id)); | 384 | |
| 385 | // We succeeded. | ||
| 386 | R_SUCCEED(); | ||
| 387 | } | ||
| 407 | 388 | ||
| 389 | Result SharedBufferManager::GetSharedFrameBufferAcquirableEvent(Kernel::KReadableEvent** out_event, | ||
| 390 | u64 layer_id) { | ||
| 408 | // Get the producer. | 391 | // Get the producer. |
| 409 | auto& producer = layer->GetBufferQueue(); | 392 | std::shared_ptr<android::BufferQueueProducer> producer; |
| 393 | R_TRY(m_container.GetLayerProducerHandle(std::addressof(producer), layer_id)); | ||
| 410 | 394 | ||
| 411 | // Set the event. | 395 | // Set the event. |
| 412 | *out_event = std::addressof(producer.GetNativeHandle()); | 396 | *out_event = producer->GetNativeHandle({}); |
| 413 | 397 | ||
| 414 | // We succeeded. | 398 | // We succeeded. |
| 415 | R_SUCCEED(); | 399 | R_SUCCEED(); |
| 416 | } | 400 | } |
| 417 | 401 | ||
| 418 | Result FbShareBufferManager::WriteAppletCaptureBuffer(bool* out_was_written, s32* out_layer_index) { | 402 | Result SharedBufferManager::WriteAppletCaptureBuffer(bool* out_was_written, s32* out_layer_index) { |
| 419 | std::vector<u8> capture_buffer(m_system.GPU().GetAppletCaptureBuffer()); | 403 | std::vector<u8> capture_buffer(m_system.GPU().GetAppletCaptureBuffer()); |
| 420 | Common::ScratchBuffer<u32> scratch; | 404 | Common::ScratchBuffer<u32> scratch; |
| 421 | 405 | ||
| @@ -444,4 +428,4 @@ Result FbShareBufferManager::WriteAppletCaptureBuffer(bool* out_was_written, s32 | |||
| 444 | R_SUCCEED(); | 428 | R_SUCCEED(); |
| 445 | } | 429 | } |
| 446 | 430 | ||
| 447 | } // namespace Service::Nvnflinger | 431 | } // namespace Service::VI |
diff --git a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.h b/src/core/hle/service/vi/shared_buffer_manager.h index b79a7d23a..7c9bb7199 100644 --- a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.h +++ b/src/core/hle/service/vi/shared_buffer_manager.h | |||
| @@ -8,15 +8,27 @@ | |||
| 8 | #include "common/math_util.h" | 8 | #include "common/math_util.h" |
| 9 | #include "core/hle/service/nvdrv/core/container.h" | 9 | #include "core/hle/service/nvdrv/core/container.h" |
| 10 | #include "core/hle/service/nvdrv/nvdata.h" | 10 | #include "core/hle/service/nvdrv/nvdata.h" |
| 11 | #include "core/hle/service/nvnflinger/hwc_layer.h" | ||
| 12 | #include "core/hle/service/nvnflinger/nvnflinger.h" | 11 | #include "core/hle/service/nvnflinger/nvnflinger.h" |
| 13 | #include "core/hle/service/nvnflinger/ui/fence.h" | 12 | #include "core/hle/service/nvnflinger/ui/fence.h" |
| 14 | 13 | ||
| 15 | namespace Kernel { | 14 | namespace Kernel { |
| 16 | class KPageGroup; | 15 | class KPageGroup; |
| 16 | class KReadableEvent; | ||
| 17 | } // namespace Kernel | ||
| 18 | |||
| 19 | namespace Service::android { | ||
| 20 | class BufferQueueProducer; | ||
| 21 | } | ||
| 22 | |||
| 23 | namespace Service::Nvidia { | ||
| 24 | class Module; | ||
| 17 | } | 25 | } |
| 18 | 26 | ||
| 19 | namespace Service::Nvnflinger { | 27 | union Result; |
| 28 | |||
| 29 | namespace Service::VI { | ||
| 30 | |||
| 31 | class Container; | ||
| 20 | 32 | ||
| 21 | struct SharedMemorySlot { | 33 | struct SharedMemorySlot { |
| 22 | u64 buffer_offset; | 34 | u64 buffer_offset; |
| @@ -32,17 +44,17 @@ struct SharedMemoryPoolLayout { | |||
| 32 | }; | 44 | }; |
| 33 | static_assert(sizeof(SharedMemoryPoolLayout) == 0x188, "SharedMemoryPoolLayout has wrong size"); | 45 | static_assert(sizeof(SharedMemoryPoolLayout) == 0x188, "SharedMemoryPoolLayout has wrong size"); |
| 34 | 46 | ||
| 35 | struct FbShareSession; | 47 | struct SharedBufferSession; |
| 36 | 48 | ||
| 37 | class FbShareBufferManager final { | 49 | class SharedBufferManager final { |
| 38 | public: | 50 | public: |
| 39 | explicit FbShareBufferManager(Core::System& system, Nvnflinger& flinger, | 51 | explicit SharedBufferManager(Core::System& system, Container& container, |
| 40 | std::shared_ptr<Nvidia::Module> nvdrv); | 52 | std::shared_ptr<Nvidia::Module> nvdrv); |
| 41 | ~FbShareBufferManager(); | 53 | ~SharedBufferManager(); |
| 42 | 54 | ||
| 43 | Result Initialize(Kernel::KProcess* owner_process, u64* out_buffer_id, u64* out_layer_handle, | 55 | Result CreateSession(Kernel::KProcess* owner_process, u64* out_buffer_id, u64* out_layer_handle, |
| 44 | u64 display_id, LayerBlending blending); | 56 | u64 display_id, bool enable_blending); |
| 45 | void Finalize(Kernel::KProcess* owner_process); | 57 | void DestroySession(Kernel::KProcess* owner_process); |
| 46 | 58 | ||
| 47 | Result GetSharedBufferMemoryHandleId(u64* out_buffer_size, s32* out_nvmap_handle, | 59 | Result GetSharedBufferMemoryHandleId(u64* out_buffer_size, s32* out_nvmap_handle, |
| 48 | SharedMemoryPoolLayout* out_pool_layout, u64 buffer_id, | 60 | SharedMemoryPoolLayout* out_pool_layout, u64 buffer_id, |
| @@ -51,32 +63,30 @@ public: | |||
| 51 | s64* out_target_slot, u64 layer_id); | 63 | s64* out_target_slot, u64 layer_id); |
| 52 | Result PresentSharedFrameBuffer(android::Fence fence, Common::Rectangle<s32> crop_region, | 64 | Result PresentSharedFrameBuffer(android::Fence fence, Common::Rectangle<s32> crop_region, |
| 53 | u32 transform, s32 swap_interval, u64 layer_id, s64 slot); | 65 | u32 transform, s32 swap_interval, u64 layer_id, s64 slot); |
| 66 | Result CancelSharedFrameBuffer(u64 layer_id, s64 slot); | ||
| 54 | Result GetSharedFrameBufferAcquirableEvent(Kernel::KReadableEvent** out_event, u64 layer_id); | 67 | Result GetSharedFrameBufferAcquirableEvent(Kernel::KReadableEvent** out_event, u64 layer_id); |
| 55 | 68 | ||
| 56 | Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_layer_index); | 69 | Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_layer_index); |
| 57 | 70 | ||
| 58 | private: | 71 | private: |
| 59 | Result GetLayerFromId(VI::Layer** out_layer, u64 layer_id); | ||
| 60 | |||
| 61 | private: | ||
| 62 | u64 m_next_buffer_id = 1; | 72 | u64 m_next_buffer_id = 1; |
| 63 | u64 m_display_id = 0; | 73 | u64 m_display_id = 0; |
| 64 | u64 m_buffer_id = 0; | 74 | u64 m_buffer_id = 0; |
| 65 | SharedMemoryPoolLayout m_pool_layout = {}; | 75 | SharedMemoryPoolLayout m_pool_layout = {}; |
| 66 | std::map<u64, FbShareSession> m_sessions; | 76 | std::map<u64, SharedBufferSession> m_sessions; |
| 67 | std::unique_ptr<Kernel::KPageGroup> m_buffer_page_group; | 77 | std::unique_ptr<Kernel::KPageGroup> m_buffer_page_group; |
| 68 | 78 | ||
| 69 | std::mutex m_guard; | 79 | std::mutex m_guard; |
| 70 | Core::System& m_system; | 80 | Core::System& m_system; |
| 71 | Nvnflinger& m_flinger; | 81 | Container& m_container; |
| 72 | std::shared_ptr<Nvidia::Module> m_nvdrv; | 82 | const std::shared_ptr<Nvidia::Module> m_nvdrv; |
| 73 | }; | 83 | }; |
| 74 | 84 | ||
| 75 | struct FbShareSession { | 85 | struct SharedBufferSession { |
| 76 | Nvidia::DeviceFD nvmap_fd = {}; | 86 | Nvidia::DeviceFD nvmap_fd = {}; |
| 77 | Nvidia::NvCore::SessionId session_id = {}; | 87 | Nvidia::NvCore::SessionId session_id = {}; |
| 78 | u64 layer_id = {}; | 88 | u64 layer_id = {}; |
| 79 | u32 buffer_nvmap_handle = 0; | 89 | u32 buffer_nvmap_handle = 0; |
| 80 | }; | 90 | }; |
| 81 | 91 | ||
| 82 | } // namespace Service::Nvnflinger | 92 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/system_display_service.cpp b/src/core/hle/service/vi/system_display_service.cpp index 1e1cfc817..c3c50b07b 100644 --- a/src/core/hle/service/vi/system_display_service.cpp +++ b/src/core/hle/service/vi/system_display_service.cpp | |||
| @@ -3,15 +3,15 @@ | |||
| 3 | 3 | ||
| 4 | #include "common/settings.h" | 4 | #include "common/settings.h" |
| 5 | #include "core/hle/service/cmif_serialization.h" | 5 | #include "core/hle/service/cmif_serialization.h" |
| 6 | #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" | 6 | #include "core/hle/service/vi/container.h" |
| 7 | #include "core/hle/service/vi/system_display_service.h" | 7 | #include "core/hle/service/vi/system_display_service.h" |
| 8 | #include "core/hle/service/vi/vi_types.h" | 8 | #include "core/hle/service/vi/vi_types.h" |
| 9 | 9 | ||
| 10 | namespace Service::VI { | 10 | namespace Service::VI { |
| 11 | 11 | ||
| 12 | ISystemDisplayService::ISystemDisplayService(Core::System& system_, | 12 | ISystemDisplayService::ISystemDisplayService(Core::System& system_, |
| 13 | Nvnflinger::Nvnflinger& nvnflinger) | 13 | std::shared_ptr<Container> container) |
| 14 | : ServiceFramework{system_, "ISystemDisplayService"}, m_nvnflinger{nvnflinger} { | 14 | : ServiceFramework{system_, "ISystemDisplayService"}, m_container{std::move(container)} { |
| 15 | // clang-format off | 15 | // clang-format off |
| 16 | static const FunctionInfo functions[] = { | 16 | static const FunctionInfo functions[] = { |
| 17 | {1200, nullptr, "GetZOrderCountMin"}, | 17 | {1200, nullptr, "GetZOrderCountMin"}, |
| @@ -29,7 +29,7 @@ ISystemDisplayService::ISystemDisplayService(Core::System& system_, | |||
| 29 | {2400, nullptr, "OpenIndirectLayer"}, | 29 | {2400, nullptr, "OpenIndirectLayer"}, |
| 30 | {2401, nullptr, "CloseIndirectLayer"}, | 30 | {2401, nullptr, "CloseIndirectLayer"}, |
| 31 | {2402, nullptr, "FlipIndirectLayer"}, | 31 | {2402, nullptr, "FlipIndirectLayer"}, |
| 32 | {3000, nullptr, "ListDisplayModes"}, | 32 | {3000, C<&ISystemDisplayService::ListDisplayModes>, "ListDisplayModes"}, |
| 33 | {3001, nullptr, "ListDisplayRgbRanges"}, | 33 | {3001, nullptr, "ListDisplayRgbRanges"}, |
| 34 | {3002, nullptr, "ListDisplayContentTypes"}, | 34 | {3002, nullptr, "ListDisplayContentTypes"}, |
| 35 | {3200, C<&ISystemDisplayService::GetDisplayMode>, "GetDisplayMode"}, | 35 | {3200, C<&ISystemDisplayService::GetDisplayMode>, "GetDisplayMode"}, |
| @@ -59,7 +59,7 @@ ISystemDisplayService::ISystemDisplayService(Core::System& system_, | |||
| 59 | {8255, C<&ISystemDisplayService::PresentSharedFrameBuffer>, "PresentSharedFrameBuffer"}, | 59 | {8255, C<&ISystemDisplayService::PresentSharedFrameBuffer>, "PresentSharedFrameBuffer"}, |
| 60 | {8256, C<&ISystemDisplayService::GetSharedFrameBufferAcquirableEvent>, "GetSharedFrameBufferAcquirableEvent"}, | 60 | {8256, C<&ISystemDisplayService::GetSharedFrameBufferAcquirableEvent>, "GetSharedFrameBufferAcquirableEvent"}, |
| 61 | {8257, nullptr, "FillSharedFrameBufferColor"}, | 61 | {8257, nullptr, "FillSharedFrameBufferColor"}, |
| 62 | {8258, nullptr, "CancelSharedFrameBuffer"}, | 62 | {8258, C<&ISystemDisplayService::CancelSharedFrameBuffer>, "CancelSharedFrameBuffer"}, |
| 63 | {9000, nullptr, "GetDp2hdmiController"}, | 63 | {9000, nullptr, "GetDp2hdmiController"}, |
| 64 | }; | 64 | }; |
| 65 | // clang-format on | 65 | // clang-format on |
| @@ -80,31 +80,50 @@ Result ISystemDisplayService::SetLayerVisibility(bool visible, u64 layer_id) { | |||
| 80 | R_SUCCEED(); | 80 | R_SUCCEED(); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | Result ISystemDisplayService::GetDisplayMode(Out<u32> out_width, Out<u32> out_height, | 83 | Result ISystemDisplayService::ListDisplayModes( |
| 84 | Out<f32> out_refresh_rate, Out<u32> out_unknown) { | 84 | Out<u64> out_count, u64 display_id, |
| 85 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 85 | OutArray<DisplayMode, BufferAttr_HipcMapAlias> out_display_modes) { |
| 86 | LOG_WARNING(Service_VI, "(STUBBED) called, display_id={}", display_id); | ||
| 87 | |||
| 88 | if (!out_display_modes.empty()) { | ||
| 89 | out_display_modes[0] = { | ||
| 90 | .width = 1920, | ||
| 91 | .height = 1080, | ||
| 92 | .refresh_rate = 60.f, | ||
| 93 | .unknown = {}, | ||
| 94 | }; | ||
| 95 | *out_count = 1; | ||
| 96 | } else { | ||
| 97 | *out_count = 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | R_SUCCEED(); | ||
| 101 | } | ||
| 102 | |||
| 103 | Result ISystemDisplayService::GetDisplayMode(Out<DisplayMode> out_display_mode, u64 display_id) { | ||
| 104 | LOG_WARNING(Service_VI, "(STUBBED) called, display_id={}", display_id); | ||
| 86 | 105 | ||
| 87 | if (Settings::IsDockedMode()) { | 106 | if (Settings::IsDockedMode()) { |
| 88 | *out_width = static_cast<u32>(DisplayResolution::DockedWidth); | 107 | out_display_mode->width = static_cast<u32>(DisplayResolution::DockedWidth); |
| 89 | *out_height = static_cast<u32>(DisplayResolution::DockedHeight); | 108 | out_display_mode->height = static_cast<u32>(DisplayResolution::DockedHeight); |
| 90 | } else { | 109 | } else { |
| 91 | *out_width = static_cast<u32>(DisplayResolution::UndockedWidth); | 110 | out_display_mode->width = static_cast<u32>(DisplayResolution::UndockedWidth); |
| 92 | *out_height = static_cast<u32>(DisplayResolution::UndockedHeight); | 111 | out_display_mode->height = static_cast<u32>(DisplayResolution::UndockedHeight); |
| 93 | } | 112 | } |
| 94 | 113 | ||
| 95 | *out_refresh_rate = 60.f; // This wouldn't seem to be correct for 30 fps games. | 114 | out_display_mode->refresh_rate = 60.f; // This wouldn't seem to be correct for 30 fps games. |
| 96 | *out_unknown = 0; | 115 | out_display_mode->unknown = 0; |
| 97 | 116 | ||
| 98 | R_SUCCEED(); | 117 | R_SUCCEED(); |
| 99 | } | 118 | } |
| 100 | 119 | ||
| 101 | Result ISystemDisplayService::GetSharedBufferMemoryHandleId( | 120 | Result ISystemDisplayService::GetSharedBufferMemoryHandleId( |
| 102 | Out<s32> out_nvmap_handle, Out<u64> out_size, | 121 | Out<s32> out_nvmap_handle, Out<u64> out_size, |
| 103 | OutLargeData<Nvnflinger::SharedMemoryPoolLayout, BufferAttr_HipcMapAlias> out_pool_layout, | 122 | OutLargeData<SharedMemoryPoolLayout, BufferAttr_HipcMapAlias> out_pool_layout, u64 buffer_id, |
| 104 | u64 buffer_id, ClientAppletResourceUserId aruid) { | 123 | ClientAppletResourceUserId aruid) { |
| 105 | LOG_INFO(Service_VI, "called. buffer_id={}, aruid={:#x}", buffer_id, aruid.pid); | 124 | LOG_INFO(Service_VI, "called. buffer_id={}, aruid={:#x}", buffer_id, aruid.pid); |
| 106 | 125 | ||
| 107 | R_RETURN(m_nvnflinger.GetSystemBufferManager().GetSharedBufferMemoryHandleId( | 126 | R_RETURN(m_container->GetSharedBufferManager()->GetSharedBufferMemoryHandleId( |
| 108 | out_size, out_nvmap_handle, out_pool_layout, buffer_id, aruid.pid)); | 127 | out_size, out_nvmap_handle, out_pool_layout, buffer_id, aruid.pid)); |
| 109 | } | 128 | } |
| 110 | 129 | ||
| @@ -122,7 +141,7 @@ Result ISystemDisplayService::AcquireSharedFrameBuffer(Out<android::Fence> out_f | |||
| 122 | Out<std::array<s32, 4>> out_slots, | 141 | Out<std::array<s32, 4>> out_slots, |
| 123 | Out<s64> out_target_slot, u64 layer_id) { | 142 | Out<s64> out_target_slot, u64 layer_id) { |
| 124 | LOG_DEBUG(Service_VI, "called"); | 143 | LOG_DEBUG(Service_VI, "called"); |
| 125 | R_RETURN(m_nvnflinger.GetSystemBufferManager().AcquireSharedFrameBuffer( | 144 | R_RETURN(m_container->GetSharedBufferManager()->AcquireSharedFrameBuffer( |
| 126 | out_fence, *out_slots, out_target_slot, layer_id)); | 145 | out_fence, *out_slots, out_target_slot, layer_id)); |
| 127 | } | 146 | } |
| 128 | 147 | ||
| @@ -131,15 +150,20 @@ Result ISystemDisplayService::PresentSharedFrameBuffer(android::Fence fence, | |||
| 131 | u32 window_transform, s32 swap_interval, | 150 | u32 window_transform, s32 swap_interval, |
| 132 | u64 layer_id, s64 surface_id) { | 151 | u64 layer_id, s64 surface_id) { |
| 133 | LOG_DEBUG(Service_VI, "called"); | 152 | LOG_DEBUG(Service_VI, "called"); |
| 134 | R_RETURN(m_nvnflinger.GetSystemBufferManager().PresentSharedFrameBuffer( | 153 | R_RETURN(m_container->GetSharedBufferManager()->PresentSharedFrameBuffer( |
| 135 | fence, crop_region, window_transform, swap_interval, layer_id, surface_id)); | 154 | fence, crop_region, window_transform, swap_interval, layer_id, surface_id)); |
| 136 | } | 155 | } |
| 137 | 156 | ||
| 138 | Result ISystemDisplayService::GetSharedFrameBufferAcquirableEvent( | 157 | Result ISystemDisplayService::GetSharedFrameBufferAcquirableEvent( |
| 139 | OutCopyHandle<Kernel::KReadableEvent> out_event, u64 layer_id) { | 158 | OutCopyHandle<Kernel::KReadableEvent> out_event, u64 layer_id) { |
| 140 | LOG_DEBUG(Service_VI, "called"); | 159 | LOG_DEBUG(Service_VI, "called"); |
| 141 | R_RETURN(m_nvnflinger.GetSystemBufferManager().GetSharedFrameBufferAcquirableEvent(out_event, | 160 | R_RETURN(m_container->GetSharedBufferManager()->GetSharedFrameBufferAcquirableEvent(out_event, |
| 142 | layer_id)); | 161 | layer_id)); |
| 162 | } | ||
| 163 | |||
| 164 | Result ISystemDisplayService::CancelSharedFrameBuffer(u64 layer_id, s64 slot) { | ||
| 165 | LOG_DEBUG(Service_VI, "called"); | ||
| 166 | R_RETURN(m_container->GetSharedBufferManager()->CancelSharedFrameBuffer(layer_id, slot)); | ||
| 143 | } | 167 | } |
| 144 | 168 | ||
| 145 | } // namespace Service::VI | 169 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/system_display_service.h b/src/core/hle/service/vi/system_display_service.h index cfcb196fd..7228d826e 100644 --- a/src/core/hle/service/vi/system_display_service.h +++ b/src/core/hle/service/vi/system_display_service.h | |||
| @@ -5,27 +5,28 @@ | |||
| 5 | #include "core/hle/service/cmif_types.h" | 5 | #include "core/hle/service/cmif_types.h" |
| 6 | #include "core/hle/service/nvnflinger/ui/fence.h" | 6 | #include "core/hle/service/nvnflinger/ui/fence.h" |
| 7 | #include "core/hle/service/service.h" | 7 | #include "core/hle/service/service.h" |
| 8 | 8 | #include "core/hle/service/vi/shared_buffer_manager.h" | |
| 9 | namespace Service::Nvnflinger { | ||
| 10 | struct SharedMemoryPoolLayout; | ||
| 11 | } | ||
| 12 | 9 | ||
| 13 | namespace Service::VI { | 10 | namespace Service::VI { |
| 11 | struct DisplayMode; | ||
| 12 | |||
| 13 | class Container; | ||
| 14 | 14 | ||
| 15 | class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> { | 15 | class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> { |
| 16 | public: | 16 | public: |
| 17 | explicit ISystemDisplayService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger); | 17 | explicit ISystemDisplayService(Core::System& system_, std::shared_ptr<Container> container); |
| 18 | ~ISystemDisplayService() override; | 18 | ~ISystemDisplayService() override; |
| 19 | 19 | ||
| 20 | private: | 20 | private: |
| 21 | Result SetLayerZ(u32 z_value, u64 layer_id); | 21 | Result SetLayerZ(u32 z_value, u64 layer_id); |
| 22 | Result SetLayerVisibility(bool visible, u64 layer_id); | 22 | Result SetLayerVisibility(bool visible, u64 layer_id); |
| 23 | Result GetDisplayMode(Out<u32> out_width, Out<u32> out_height, Out<f32> out_refresh_rate, | 23 | Result ListDisplayModes(Out<u64> out_count, u64 display_id, |
| 24 | Out<u32> out_unknown); | 24 | OutArray<DisplayMode, BufferAttr_HipcMapAlias> out_display_modes); |
| 25 | Result GetDisplayMode(Out<DisplayMode> out_display_mode, u64 display_id); | ||
| 25 | 26 | ||
| 26 | Result GetSharedBufferMemoryHandleId( | 27 | Result GetSharedBufferMemoryHandleId( |
| 27 | Out<s32> out_nvmap_handle, Out<u64> out_size, | 28 | Out<s32> out_nvmap_handle, Out<u64> out_size, |
| 28 | OutLargeData<Nvnflinger::SharedMemoryPoolLayout, BufferAttr_HipcMapAlias> out_pool_layout, | 29 | OutLargeData<SharedMemoryPoolLayout, BufferAttr_HipcMapAlias> out_pool_layout, |
| 29 | u64 buffer_id, ClientAppletResourceUserId aruid); | 30 | u64 buffer_id, ClientAppletResourceUserId aruid); |
| 30 | Result OpenSharedLayer(u64 layer_id); | 31 | Result OpenSharedLayer(u64 layer_id); |
| 31 | Result ConnectSharedLayer(u64 layer_id); | 32 | Result ConnectSharedLayer(u64 layer_id); |
| @@ -37,9 +38,10 @@ private: | |||
| 37 | Result PresentSharedFrameBuffer(android::Fence fence, Common::Rectangle<s32> crop_region, | 38 | Result PresentSharedFrameBuffer(android::Fence fence, Common::Rectangle<s32> crop_region, |
| 38 | u32 window_transform, s32 swap_interval, u64 layer_id, | 39 | u32 window_transform, s32 swap_interval, u64 layer_id, |
| 39 | s64 surface_id); | 40 | s64 surface_id); |
| 41 | Result CancelSharedFrameBuffer(u64 layer_id, s64 slot); | ||
| 40 | 42 | ||
| 41 | private: | 43 | private: |
| 42 | Nvnflinger::Nvnflinger& m_nvnflinger; | 44 | const std::shared_ptr<Container> m_container; |
| 43 | }; | 45 | }; |
| 44 | 46 | ||
| 45 | } // namespace Service::VI | 47 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/system_root_service.cpp b/src/core/hle/service/vi/system_root_service.cpp index 8789b4cfb..3489727d8 100644 --- a/src/core/hle/service/vi/system_root_service.cpp +++ b/src/core/hle/service/vi/system_root_service.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include "core/hle/service/cmif_serialization.h" | 4 | #include "core/hle/service/cmif_serialization.h" |
| 5 | #include "core/hle/service/vi/application_display_service.h" | 5 | #include "core/hle/service/vi/application_display_service.h" |
| 6 | #include "core/hle/service/vi/container.h" | ||
| 6 | #include "core/hle/service/vi/service_creator.h" | 7 | #include "core/hle/service/vi/service_creator.h" |
| 7 | #include "core/hle/service/vi/system_root_service.h" | 8 | #include "core/hle/service/vi/system_root_service.h" |
| 8 | #include "core/hle/service/vi/vi.h" | 9 | #include "core/hle/service/vi/vi.h" |
| @@ -10,10 +11,8 @@ | |||
| 10 | 11 | ||
| 11 | namespace Service::VI { | 12 | namespace Service::VI { |
| 12 | 13 | ||
| 13 | ISystemRootService::ISystemRootService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger, | 14 | ISystemRootService::ISystemRootService(Core::System& system_, std::shared_ptr<Container> container) |
| 14 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server) | 15 | : ServiceFramework{system_, "vi:s"}, m_container{std::move(container)} { |
| 15 | : ServiceFramework{system_, "vi:s"}, m_nvnflinger{nvnflinger}, m_hos_binder_driver_server{ | ||
| 16 | hos_binder_driver_server} { | ||
| 17 | static const FunctionInfo functions[] = { | 16 | static const FunctionInfo functions[] = { |
| 18 | {1, C<&ISystemRootService::GetDisplayService>, "GetDisplayService"}, | 17 | {1, C<&ISystemRootService::GetDisplayService>, "GetDisplayService"}, |
| 19 | {3, nullptr, "GetDisplayServiceWithProxyNameExchange"}, | 18 | {3, nullptr, "GetDisplayServiceWithProxyNameExchange"}, |
| @@ -26,8 +25,8 @@ ISystemRootService::~ISystemRootService() = default; | |||
| 26 | Result ISystemRootService::GetDisplayService( | 25 | Result ISystemRootService::GetDisplayService( |
| 27 | Out<SharedPointer<IApplicationDisplayService>> out_application_display_service, Policy policy) { | 26 | Out<SharedPointer<IApplicationDisplayService>> out_application_display_service, Policy policy) { |
| 28 | LOG_DEBUG(Service_VI, "called"); | 27 | LOG_DEBUG(Service_VI, "called"); |
| 29 | R_RETURN(GetApplicationDisplayService(out_application_display_service, system, m_nvnflinger, | 28 | R_RETURN(GetApplicationDisplayService(out_application_display_service, system, m_container, |
| 30 | m_hos_binder_driver_server, Permission::System, policy)); | 29 | Permission::System, policy)); |
| 31 | } | 30 | } |
| 32 | 31 | ||
| 33 | } // namespace Service::VI | 32 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/system_root_service.h b/src/core/hle/service/vi/system_root_service.h index 2c547faa5..9d5aa53d3 100644 --- a/src/core/hle/service/vi/system_root_service.h +++ b/src/core/hle/service/vi/system_root_service.h | |||
| @@ -10,20 +10,15 @@ namespace Core { | |||
| 10 | class System; | 10 | class System; |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | namespace Service::Nvnflinger { | ||
| 14 | class HosBinderDriverServer; | ||
| 15 | class Nvnflinger; | ||
| 16 | } // namespace Service::Nvnflinger | ||
| 17 | |||
| 18 | namespace Service::VI { | 13 | namespace Service::VI { |
| 19 | 14 | ||
| 15 | class Container; | ||
| 20 | class IApplicationDisplayService; | 16 | class IApplicationDisplayService; |
| 21 | enum class Policy : u32; | 17 | enum class Policy : u32; |
| 22 | 18 | ||
| 23 | class ISystemRootService final : public ServiceFramework<ISystemRootService> { | 19 | class ISystemRootService final : public ServiceFramework<ISystemRootService> { |
| 24 | public: | 20 | public: |
| 25 | explicit ISystemRootService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger, | 21 | explicit ISystemRootService(Core::System& system_, std::shared_ptr<Container> container); |
| 26 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server); | ||
| 27 | ~ISystemRootService() override; | 22 | ~ISystemRootService() override; |
| 28 | 23 | ||
| 29 | private: | 24 | private: |
| @@ -31,8 +26,7 @@ private: | |||
| 31 | Out<SharedPointer<IApplicationDisplayService>> out_application_display_service, | 26 | Out<SharedPointer<IApplicationDisplayService>> out_application_display_service, |
| 32 | Policy policy); | 27 | Policy policy); |
| 33 | 28 | ||
| 34 | Nvnflinger::Nvnflinger& m_nvnflinger; | 29 | const std::shared_ptr<Container> m_container; |
| 35 | Nvnflinger::HosBinderDriverServer& m_hos_binder_driver_server; | ||
| 36 | }; | 30 | }; |
| 37 | 31 | ||
| 38 | } // namespace Service::VI | 32 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 304e589b7..b388efaf6 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -1,25 +1,30 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/core.h" | ||
| 4 | #include "core/hle/service/server_manager.h" | 5 | #include "core/hle/service/server_manager.h" |
| 5 | #include "core/hle/service/vi/application_display_service.h" | ||
| 6 | #include "core/hle/service/vi/application_root_service.h" | 6 | #include "core/hle/service/vi/application_root_service.h" |
| 7 | #include "core/hle/service/vi/container.h" | ||
| 7 | #include "core/hle/service/vi/manager_root_service.h" | 8 | #include "core/hle/service/vi/manager_root_service.h" |
| 8 | #include "core/hle/service/vi/system_root_service.h" | 9 | #include "core/hle/service/vi/system_root_service.h" |
| 9 | #include "core/hle/service/vi/vi.h" | 10 | #include "core/hle/service/vi/vi.h" |
| 10 | 11 | ||
| 11 | namespace Service::VI { | 12 | namespace Service::VI { |
| 12 | 13 | ||
| 13 | void LoopProcess(Core::System& system, Nvnflinger::Nvnflinger& nvnflinger, | 14 | void LoopProcess(Core::System& system, std::stop_token token) { |
| 14 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server) { | 15 | const auto container = std::make_shared<Container>(system); |
| 16 | |||
| 15 | auto server_manager = std::make_unique<ServerManager>(system); | 17 | auto server_manager = std::make_unique<ServerManager>(system); |
| 16 | 18 | ||
| 17 | server_manager->RegisterNamedService("vi:m", std::make_shared<IManagerRootService>( | 19 | server_manager->RegisterNamedService("vi:m", |
| 18 | system, nvnflinger, hos_binder_driver_server)); | 20 | std::make_shared<IManagerRootService>(system, container)); |
| 21 | server_manager->RegisterNamedService("vi:s", | ||
| 22 | std::make_shared<ISystemRootService>(system, container)); | ||
| 19 | server_manager->RegisterNamedService( | 23 | server_manager->RegisterNamedService( |
| 20 | "vi:s", std::make_shared<ISystemRootService>(system, nvnflinger, hos_binder_driver_server)); | 24 | "vi:u", std::make_shared<IApplicationRootService>(system, container)); |
| 21 | server_manager->RegisterNamedService("vi:u", std::make_shared<IApplicationRootService>( | 25 | |
| 22 | system, nvnflinger, hos_binder_driver_server)); | 26 | std::stop_callback cb(token, [=] { container->OnTerminate(); }); |
| 27 | |||
| 23 | ServerManager::RunServer(std::move(server_manager)); | 28 | ServerManager::RunServer(std::move(server_manager)); |
| 24 | } | 29 | } |
| 25 | 30 | ||
diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h index 8e681370d..7c1f350d8 100644 --- a/src/core/hle/service/vi/vi.h +++ b/src/core/hle/service/vi/vi.h | |||
| @@ -3,18 +3,14 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "common/polyfill_thread.h" | ||
| 7 | |||
| 6 | namespace Core { | 8 | namespace Core { |
| 7 | class System; | 9 | class System; |
| 8 | } | 10 | } |
| 9 | 11 | ||
| 10 | namespace Service::Nvnflinger { | ||
| 11 | class HosBinderDriverServer; | ||
| 12 | class Nvnflinger; | ||
| 13 | } // namespace Service::Nvnflinger | ||
| 14 | |||
| 15 | namespace Service::VI { | 12 | namespace Service::VI { |
| 16 | 13 | ||
| 17 | void LoopProcess(Core::System& system, Nvnflinger::Nvnflinger& nvnflinger, | 14 | void LoopProcess(Core::System& system, std::stop_token token); |
| 18 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server); | ||
| 19 | 15 | ||
| 20 | } // namespace Service::VI | 16 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/vi_types.h b/src/core/hle/service/vi/vi_types.h index 91e4b380c..95ff66358 100644 --- a/src/core/hle/service/vi/vi_types.h +++ b/src/core/hle/service/vi/vi_types.h | |||
| @@ -66,9 +66,17 @@ struct DisplayInfo { | |||
| 66 | }; | 66 | }; |
| 67 | static_assert(sizeof(DisplayInfo) == 0x60, "DisplayInfo has wrong size"); | 67 | static_assert(sizeof(DisplayInfo) == 0x60, "DisplayInfo has wrong size"); |
| 68 | 68 | ||
| 69 | struct DisplayMode { | ||
| 70 | u32 width; | ||
| 71 | u32 height; | ||
| 72 | f32 refresh_rate; | ||
| 73 | u32 unknown; | ||
| 74 | }; | ||
| 75 | static_assert(sizeof(DisplayMode) == 0x10, "DisplayMode has wrong size"); | ||
| 76 | |||
| 69 | class NativeWindow final { | 77 | class NativeWindow final { |
| 70 | public: | 78 | public: |
| 71 | constexpr explicit NativeWindow(u32 id_) : id{id_} {} | 79 | constexpr explicit NativeWindow(s32 id_) : id{static_cast<u64>(id_)} {} |
| 72 | constexpr explicit NativeWindow(const NativeWindow& other) = default; | 80 | constexpr explicit NativeWindow(const NativeWindow& other) = default; |
| 73 | 81 | ||
| 74 | private: | 82 | private: |
diff --git a/src/core/hle/service/vi/vsync_manager.cpp b/src/core/hle/service/vi/vsync_manager.cpp new file mode 100644 index 000000000..bdc4dfa96 --- /dev/null +++ b/src/core/hle/service/vi/vsync_manager.cpp | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/service/os/event.h" | ||
| 5 | #include "core/hle/service/vi/vsync_manager.h" | ||
| 6 | |||
| 7 | namespace Service::VI { | ||
| 8 | |||
| 9 | VsyncManager::VsyncManager() = default; | ||
| 10 | VsyncManager::~VsyncManager() = default; | ||
| 11 | |||
| 12 | void VsyncManager::SignalVsync() { | ||
| 13 | for (auto* event : m_vsync_events) { | ||
| 14 | event->Signal(); | ||
| 15 | } | ||
| 16 | } | ||
| 17 | |||
| 18 | void VsyncManager::LinkVsyncEvent(Event* event) { | ||
| 19 | m_vsync_events.insert(event); | ||
| 20 | } | ||
| 21 | |||
| 22 | void VsyncManager::UnlinkVsyncEvent(Event* event) { | ||
| 23 | m_vsync_events.erase(event); | ||
| 24 | } | ||
| 25 | |||
| 26 | } // namespace Service::VI | ||
diff --git a/src/core/hle/service/vi/vsync_manager.h b/src/core/hle/service/vi/vsync_manager.h new file mode 100644 index 000000000..5d45bb5ee --- /dev/null +++ b/src/core/hle/service/vi/vsync_manager.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <set> | ||
| 7 | |||
| 8 | namespace Service { | ||
| 9 | class Event; | ||
| 10 | } | ||
| 11 | |||
| 12 | namespace Service::VI { | ||
| 13 | |||
| 14 | class DisplayList; | ||
| 15 | |||
| 16 | class VsyncManager { | ||
| 17 | public: | ||
| 18 | explicit VsyncManager(); | ||
| 19 | ~VsyncManager(); | ||
| 20 | |||
| 21 | void SignalVsync(); | ||
| 22 | void LinkVsyncEvent(Event* event); | ||
| 23 | void UnlinkVsyncEvent(Event* event); | ||
| 24 | |||
| 25 | private: | ||
| 26 | std::set<Event*> m_vsync_events; | ||
| 27 | }; | ||
| 28 | |||
| 29 | } // namespace Service::VI | ||
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index 2a32b1276..de27ec49e 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp | |||
| @@ -118,7 +118,9 @@ ResultStatus AppLoader_NCA::VerifyIntegrity(std::function<bool(size_t, size_t)> | |||
| 118 | mbedtls_sha256_starts_ret(&ctx, 0); | 118 | mbedtls_sha256_starts_ret(&ctx, 0); |
| 119 | 119 | ||
| 120 | // Ensure we maintain a clean state on exit. | 120 | // Ensure we maintain a clean state on exit. |
| 121 | SCOPE_EXIT({ mbedtls_sha256_free(&ctx); }); | 121 | SCOPE_EXIT { |
| 122 | mbedtls_sha256_free(&ctx); | ||
| 123 | }; | ||
| 122 | 124 | ||
| 123 | // Declare counters. | 125 | // Declare counters. |
| 124 | const size_t total_size = file->GetSize(); | 126 | const size_t total_size = file->GetSize(); |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index e10a4601e..8775369a4 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -831,11 +831,11 @@ struct Memory::Impl { | |||
| 831 | if (core == sys_core) [[unlikely]] { | 831 | if (core == sys_core) [[unlikely]] { |
| 832 | sys_core_guard.lock(); | 832 | sys_core_guard.lock(); |
| 833 | } | 833 | } |
| 834 | SCOPE_EXIT({ | 834 | SCOPE_EXIT { |
| 835 | if (core == sys_core) [[unlikely]] { | 835 | if (core == sys_core) [[unlikely]] { |
| 836 | sys_core_guard.unlock(); | 836 | sys_core_guard.unlock(); |
| 837 | } | 837 | } |
| 838 | }); | 838 | }; |
| 839 | gpu_device_memory->ApplyOpOnPointer(p, scratch_buffers[core], [&](DAddr address) { | 839 | gpu_device_memory->ApplyOpOnPointer(p, scratch_buffers[core], [&](DAddr address) { |
| 840 | auto& current_area = rasterizer_write_areas[core]; | 840 | auto& current_area = rasterizer_write_areas[core]; |
| 841 | PAddr subaddress = address >> YUZU_PAGEBITS; | 841 | PAddr subaddress = address >> YUZU_PAGEBITS; |
| @@ -866,11 +866,11 @@ struct Memory::Impl { | |||
| 866 | if (core == sys_core) [[unlikely]] { | 866 | if (core == sys_core) [[unlikely]] { |
| 867 | sys_core_guard.lock(); | 867 | sys_core_guard.lock(); |
| 868 | } | 868 | } |
| 869 | SCOPE_EXIT({ | 869 | SCOPE_EXIT { |
| 870 | if (core == sys_core) [[unlikely]] { | 870 | if (core == sys_core) [[unlikely]] { |
| 871 | sys_core_guard.unlock(); | 871 | sys_core_guard.unlock(); |
| 872 | } | 872 | } |
| 873 | }); | 873 | }; |
| 874 | auto& gpu = system.GPU(); | 874 | auto& gpu = system.GPU(); |
| 875 | gpu_device_memory->ApplyOpOnPointer( | 875 | gpu_device_memory->ApplyOpOnPointer( |
| 876 | p, scratch_buffers[core], [&](DAddr address) { gpu.InvalidateRegion(address, size); }); | 876 | p, scratch_buffers[core], [&](DAddr address) { gpu.InvalidateRegion(address, size); }); |
diff --git a/src/core/memory/dmnt_cheat_vm.cpp b/src/core/memory/dmnt_cheat_vm.cpp index f7097d01d..caceeec4f 100644 --- a/src/core/memory/dmnt_cheat_vm.cpp +++ b/src/core/memory/dmnt_cheat_vm.cpp | |||
| @@ -224,12 +224,12 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) { | |||
| 224 | // If we've ever seen a decode failure, return false. | 224 | // If we've ever seen a decode failure, return false. |
| 225 | bool valid = decode_success; | 225 | bool valid = decode_success; |
| 226 | CheatVmOpcode opcode = {}; | 226 | CheatVmOpcode opcode = {}; |
| 227 | SCOPE_EXIT({ | 227 | SCOPE_EXIT { |
| 228 | decode_success &= valid; | 228 | decode_success &= valid; |
| 229 | if (valid) { | 229 | if (valid) { |
| 230 | out = opcode; | 230 | out = opcode; |
| 231 | } | 231 | } |
| 232 | }); | 232 | }; |
| 233 | 233 | ||
| 234 | // Helper function for getting instruction dwords. | 234 | // Helper function for getting instruction dwords. |
| 235 | const auto GetNextDword = [&] { | 235 | const auto GetNextDword = [&] { |
diff --git a/src/hid_core/frontend/emulated_controller.cpp b/src/hid_core/frontend/emulated_controller.cpp index d9d278fa3..5cd26819c 100644 --- a/src/hid_core/frontend/emulated_controller.cpp +++ b/src/hid_core/frontend/emulated_controller.cpp | |||
| @@ -933,8 +933,9 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback, | |||
| 933 | if (index >= controller.stick_values.size()) { | 933 | if (index >= controller.stick_values.size()) { |
| 934 | return; | 934 | return; |
| 935 | } | 935 | } |
| 936 | auto trigger_guard = | 936 | auto trigger_guard = SCOPE_GUARD { |
| 937 | SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Stick, !is_configuring); }); | 937 | TriggerOnChange(ControllerTriggerType::Stick, !is_configuring); |
| 938 | }; | ||
| 938 | std::scoped_lock lock{mutex}; | 939 | std::scoped_lock lock{mutex}; |
| 939 | const auto stick_value = TransformToStick(callback); | 940 | const auto stick_value = TransformToStick(callback); |
| 940 | 941 | ||
| @@ -989,8 +990,9 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac | |||
| 989 | if (index >= controller.trigger_values.size()) { | 990 | if (index >= controller.trigger_values.size()) { |
| 990 | return; | 991 | return; |
| 991 | } | 992 | } |
| 992 | auto trigger_guard = | 993 | auto trigger_guard = SCOPE_GUARD { |
| 993 | SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Trigger, !is_configuring); }); | 994 | TriggerOnChange(ControllerTriggerType::Trigger, !is_configuring); |
| 995 | }; | ||
| 994 | std::scoped_lock lock{mutex}; | 996 | std::scoped_lock lock{mutex}; |
| 995 | const auto trigger_value = TransformToTrigger(callback); | 997 | const auto trigger_value = TransformToTrigger(callback); |
| 996 | 998 | ||
| @@ -1036,7 +1038,9 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback | |||
| 1036 | if (index >= controller.motion_values.size()) { | 1038 | if (index >= controller.motion_values.size()) { |
| 1037 | return; | 1039 | return; |
| 1038 | } | 1040 | } |
| 1039 | SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::Motion, !is_configuring); }); | 1041 | SCOPE_EXIT { |
| 1042 | TriggerOnChange(ControllerTriggerType::Motion, !is_configuring); | ||
| 1043 | }; | ||
| 1040 | std::scoped_lock lock{mutex}; | 1044 | std::scoped_lock lock{mutex}; |
| 1041 | auto& raw_status = controller.motion_values[index].raw_status; | 1045 | auto& raw_status = controller.motion_values[index].raw_status; |
| 1042 | auto& emulated = controller.motion_values[index].emulated; | 1046 | auto& emulated = controller.motion_values[index].emulated; |
| @@ -1070,8 +1074,9 @@ void EmulatedController::SetColors(const Common::Input::CallbackStatus& callback | |||
| 1070 | if (index >= controller.color_values.size()) { | 1074 | if (index >= controller.color_values.size()) { |
| 1071 | return; | 1075 | return; |
| 1072 | } | 1076 | } |
| 1073 | auto trigger_guard = | 1077 | auto trigger_guard = SCOPE_GUARD { |
| 1074 | SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Color, !is_configuring); }); | 1078 | TriggerOnChange(ControllerTriggerType::Color, !is_configuring); |
| 1079 | }; | ||
| 1075 | std::scoped_lock lock{mutex}; | 1080 | std::scoped_lock lock{mutex}; |
| 1076 | controller.color_values[index] = TransformToColor(callback); | 1081 | controller.color_values[index] = TransformToColor(callback); |
| 1077 | 1082 | ||
| @@ -1120,7 +1125,9 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac | |||
| 1120 | if (index >= controller.battery_values.size()) { | 1125 | if (index >= controller.battery_values.size()) { |
| 1121 | return; | 1126 | return; |
| 1122 | } | 1127 | } |
| 1123 | SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::Battery, !is_configuring); }); | 1128 | SCOPE_EXIT { |
| 1129 | TriggerOnChange(ControllerTriggerType::Battery, !is_configuring); | ||
| 1130 | }; | ||
| 1124 | std::scoped_lock lock{mutex}; | 1131 | std::scoped_lock lock{mutex}; |
| 1125 | controller.battery_values[index] = TransformToBattery(callback); | 1132 | controller.battery_values[index] = TransformToBattery(callback); |
| 1126 | 1133 | ||
| @@ -1183,7 +1190,9 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac | |||
| 1183 | } | 1190 | } |
| 1184 | 1191 | ||
| 1185 | void EmulatedController::SetCamera(const Common::Input::CallbackStatus& callback) { | 1192 | void EmulatedController::SetCamera(const Common::Input::CallbackStatus& callback) { |
| 1186 | SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::IrSensor, !is_configuring); }); | 1193 | SCOPE_EXIT { |
| 1194 | TriggerOnChange(ControllerTriggerType::IrSensor, !is_configuring); | ||
| 1195 | }; | ||
| 1187 | std::scoped_lock lock{mutex}; | 1196 | std::scoped_lock lock{mutex}; |
| 1188 | controller.camera_values = TransformToCamera(callback); | 1197 | controller.camera_values = TransformToCamera(callback); |
| 1189 | 1198 | ||
| @@ -1198,7 +1207,9 @@ void EmulatedController::SetCamera(const Common::Input::CallbackStatus& callback | |||
| 1198 | } | 1207 | } |
| 1199 | 1208 | ||
| 1200 | void EmulatedController::SetRingAnalog(const Common::Input::CallbackStatus& callback) { | 1209 | void EmulatedController::SetRingAnalog(const Common::Input::CallbackStatus& callback) { |
| 1201 | SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::RingController, !is_configuring); }); | 1210 | SCOPE_EXIT { |
| 1211 | TriggerOnChange(ControllerTriggerType::RingController, !is_configuring); | ||
| 1212 | }; | ||
| 1202 | std::scoped_lock lock{mutex}; | 1213 | std::scoped_lock lock{mutex}; |
| 1203 | const auto force_value = TransformToStick(callback); | 1214 | const auto force_value = TransformToStick(callback); |
| 1204 | 1215 | ||
| @@ -1212,7 +1223,9 @@ void EmulatedController::SetRingAnalog(const Common::Input::CallbackStatus& call | |||
| 1212 | } | 1223 | } |
| 1213 | 1224 | ||
| 1214 | void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) { | 1225 | void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) { |
| 1215 | SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::Nfc, !is_configuring); }); | 1226 | SCOPE_EXIT { |
| 1227 | TriggerOnChange(ControllerTriggerType::Nfc, !is_configuring); | ||
| 1228 | }; | ||
| 1216 | std::scoped_lock lock{mutex}; | 1229 | std::scoped_lock lock{mutex}; |
| 1217 | controller.nfc_values = TransformToNfc(callback); | 1230 | controller.nfc_values = TransformToNfc(callback); |
| 1218 | 1231 | ||
| @@ -1685,8 +1698,9 @@ void EmulatedController::Connect(bool use_temporary_value) { | |||
| 1685 | return; | 1698 | return; |
| 1686 | } | 1699 | } |
| 1687 | 1700 | ||
| 1688 | auto trigger_guard = | 1701 | auto trigger_guard = SCOPE_GUARD { |
| 1689 | SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Connected, !is_configuring); }); | 1702 | TriggerOnChange(ControllerTriggerType::Connected, !is_configuring); |
| 1703 | }; | ||
| 1690 | std::scoped_lock lock{connect_mutex, mutex}; | 1704 | std::scoped_lock lock{connect_mutex, mutex}; |
| 1691 | if (is_configuring) { | 1705 | if (is_configuring) { |
| 1692 | tmp_is_connected = true; | 1706 | tmp_is_connected = true; |
| @@ -1701,8 +1715,9 @@ void EmulatedController::Connect(bool use_temporary_value) { | |||
| 1701 | } | 1715 | } |
| 1702 | 1716 | ||
| 1703 | void EmulatedController::Disconnect() { | 1717 | void EmulatedController::Disconnect() { |
| 1704 | auto trigger_guard = | 1718 | auto trigger_guard = SCOPE_GUARD { |
| 1705 | SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Disconnected, !is_configuring); }); | 1719 | TriggerOnChange(ControllerTriggerType::Disconnected, !is_configuring); |
| 1720 | }; | ||
| 1706 | std::scoped_lock lock{connect_mutex, mutex}; | 1721 | std::scoped_lock lock{connect_mutex, mutex}; |
| 1707 | if (is_configuring) { | 1722 | if (is_configuring) { |
| 1708 | tmp_is_connected = false; | 1723 | tmp_is_connected = false; |
| @@ -1738,8 +1753,9 @@ NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) c | |||
| 1738 | } | 1753 | } |
| 1739 | 1754 | ||
| 1740 | void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) { | 1755 | void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) { |
| 1741 | auto trigger_guard = | 1756 | auto trigger_guard = SCOPE_GUARD { |
| 1742 | SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Type, !is_configuring); }); | 1757 | TriggerOnChange(ControllerTriggerType::Type, !is_configuring); |
| 1758 | }; | ||
| 1743 | std::scoped_lock lock{mutex, npad_mutex}; | 1759 | std::scoped_lock lock{mutex, npad_mutex}; |
| 1744 | 1760 | ||
| 1745 | if (is_configuring) { | 1761 | if (is_configuring) { |
diff --git a/src/input_common/helpers/joycon_driver.cpp b/src/input_common/helpers/joycon_driver.cpp index c9f903213..0dd1c958a 100644 --- a/src/input_common/helpers/joycon_driver.cpp +++ b/src/input_common/helpers/joycon_driver.cpp | |||
| @@ -268,7 +268,9 @@ void JoyconDriver::OnNewData(std::span<u8> buffer) { | |||
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | Common::Input::DriverResult JoyconDriver::SetPollingMode() { | 270 | Common::Input::DriverResult JoyconDriver::SetPollingMode() { |
| 271 | SCOPE_EXIT({ disable_input_thread = false; }); | 271 | SCOPE_EXIT { |
| 272 | disable_input_thread = false; | ||
| 273 | }; | ||
| 272 | disable_input_thread = true; | 274 | disable_input_thread = true; |
| 273 | 275 | ||
| 274 | rumble_protocol->EnableRumble(vibration_enabled && supported_features.vibration); | 276 | rumble_protocol->EnableRumble(vibration_enabled && supported_features.vibration); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 0031fa5fb..3f9698d6b 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp | |||
| @@ -261,7 +261,9 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) { | |||
| 261 | case Stage::Geometry: | 261 | case Stage::Geometry: |
| 262 | execution_model = spv::ExecutionModel::Geometry; | 262 | execution_model = spv::ExecutionModel::Geometry; |
| 263 | ctx.AddCapability(spv::Capability::Geometry); | 263 | ctx.AddCapability(spv::Capability::Geometry); |
| 264 | ctx.AddCapability(spv::Capability::GeometryStreams); | 264 | if (ctx.profile.support_geometry_streams) { |
| 265 | ctx.AddCapability(spv::Capability::GeometryStreams); | ||
| 266 | } | ||
| 265 | switch (ctx.runtime_info.input_topology) { | 267 | switch (ctx.runtime_info.input_topology) { |
| 266 | case InputTopology::Points: | 268 | case InputTopology::Points: |
| 267 | ctx.AddExecutionMode(main, spv::ExecutionMode::InputPoints); | 269 | ctx.AddExecutionMode(main, spv::ExecutionMode::InputPoints); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 44281e407..945cdb42b 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | |||
| @@ -60,11 +60,10 @@ public: | |||
| 60 | Add(spv::ImageOperandsMask::ConstOffsets, offsets); | 60 | Add(spv::ImageOperandsMask::ConstOffsets, offsets); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | explicit ImageOperands(EmitContext& ctx, const IR::Value& offset, Id lod, Id ms) { | 63 | explicit ImageOperands(Id lod, Id ms) { |
| 64 | if (Sirit::ValidId(lod)) { | 64 | if (Sirit::ValidId(lod)) { |
| 65 | Add(spv::ImageOperandsMask::Lod, lod); | 65 | Add(spv::ImageOperandsMask::Lod, lod); |
| 66 | } | 66 | } |
| 67 | AddOffset(ctx, offset, ImageFetchOffsetAllowed); | ||
| 68 | if (Sirit::ValidId(ms)) { | 67 | if (Sirit::ValidId(ms)) { |
| 69 | Add(spv::ImageOperandsMask::Sample, ms); | 68 | Add(spv::ImageOperandsMask::Sample, ms); |
| 70 | } | 69 | } |
| @@ -312,6 +311,43 @@ Id ImageGatherSubpixelOffset(EmitContext& ctx, const IR::TextureInstInfo& info, | |||
| 312 | return coords; | 311 | return coords; |
| 313 | } | 312 | } |
| 314 | } | 313 | } |
| 314 | |||
| 315 | void AddOffsetToCoordinates(EmitContext& ctx, const IR::TextureInstInfo& info, Id& coords, | ||
| 316 | Id offset) { | ||
| 317 | if (!Sirit::ValidId(offset)) { | ||
| 318 | return; | ||
| 319 | } | ||
| 320 | |||
| 321 | Id result_type{}; | ||
| 322 | switch (info.type) { | ||
| 323 | case TextureType::Buffer: | ||
| 324 | case TextureType::Color1D: { | ||
| 325 | result_type = ctx.U32[1]; | ||
| 326 | break; | ||
| 327 | } | ||
| 328 | case TextureType::ColorArray1D: | ||
| 329 | offset = ctx.OpCompositeConstruct(ctx.U32[2], offset, ctx.u32_zero_value); | ||
| 330 | [[fallthrough]]; | ||
| 331 | case TextureType::Color2D: | ||
| 332 | case TextureType::Color2DRect: { | ||
| 333 | result_type = ctx.U32[2]; | ||
| 334 | break; | ||
| 335 | } | ||
| 336 | case TextureType::ColorArray2D: | ||
| 337 | offset = ctx.OpCompositeConstruct(ctx.U32[3], ctx.OpCompositeExtract(ctx.U32[1], coords, 0), | ||
| 338 | ctx.OpCompositeExtract(ctx.U32[1], coords, 1), | ||
| 339 | ctx.u32_zero_value); | ||
| 340 | [[fallthrough]]; | ||
| 341 | case TextureType::Color3D: { | ||
| 342 | result_type = ctx.U32[3]; | ||
| 343 | break; | ||
| 344 | } | ||
| 345 | case TextureType::ColorCube: | ||
| 346 | case TextureType::ColorArrayCube: | ||
| 347 | return; | ||
| 348 | } | ||
| 349 | coords = ctx.OpIAdd(result_type, coords, offset); | ||
| 350 | } | ||
| 315 | } // Anonymous namespace | 351 | } // Anonymous namespace |
| 316 | 352 | ||
| 317 | Id EmitBindlessImageSampleImplicitLod(EmitContext&) { | 353 | Id EmitBindlessImageSampleImplicitLod(EmitContext&) { |
| @@ -494,9 +530,10 @@ Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, | |||
| 494 | operands.Span()); | 530 | operands.Span()); |
| 495 | } | 531 | } |
| 496 | 532 | ||
| 497 | Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | 533 | Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, |
| 498 | const IR::Value& offset, Id lod, Id ms) { | 534 | Id lod, Id ms) { |
| 499 | const auto info{inst->Flags<IR::TextureInstInfo>()}; | 535 | const auto info{inst->Flags<IR::TextureInstInfo>()}; |
| 536 | AddOffsetToCoordinates(ctx, info, coords, offset); | ||
| 500 | if (info.type == TextureType::Buffer) { | 537 | if (info.type == TextureType::Buffer) { |
| 501 | lod = Id{}; | 538 | lod = Id{}; |
| 502 | } | 539 | } |
| @@ -504,7 +541,7 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id c | |||
| 504 | // This image is multisampled, lod must be implicit | 541 | // This image is multisampled, lod must be implicit |
| 505 | lod = Id{}; | 542 | lod = Id{}; |
| 506 | } | 543 | } |
| 507 | const ImageOperands operands(ctx, offset, lod, ms); | 544 | const ImageOperands operands(lod, ms); |
| 508 | return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4], | 545 | return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4], |
| 509 | TextureImage(ctx, info, index), coords, operands.MaskOptional(), operands.Span()); | 546 | TextureImage(ctx, info, index), coords, operands.MaskOptional(), operands.Span()); |
| 510 | } | 547 | } |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index 08fcabd58..5c01b1012 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h | |||
| @@ -537,8 +537,8 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id | |||
| 537 | const IR::Value& offset, const IR::Value& offset2); | 537 | const IR::Value& offset, const IR::Value& offset2); |
| 538 | Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | 538 | Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, |
| 539 | const IR::Value& offset, const IR::Value& offset2, Id dref); | 539 | const IR::Value& offset, const IR::Value& offset2, Id dref); |
| 540 | Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | 540 | Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, |
| 541 | const IR::Value& offset, Id lod, Id ms); | 541 | Id lod, Id ms); |
| 542 | Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod, | 542 | Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod, |
| 543 | const IR::Value& skip_mips); | 543 | const IR::Value& skip_mips); |
| 544 | Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords); | 544 | Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp index 9f7b6bb4b..f60da758e 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp | |||
| @@ -129,7 +129,9 @@ void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { | |||
| 129 | if (ctx.runtime_info.convert_depth_mode && !ctx.profile.support_native_ndc) { | 129 | if (ctx.runtime_info.convert_depth_mode && !ctx.profile.support_native_ndc) { |
| 130 | ConvertDepthMode(ctx); | 130 | ConvertDepthMode(ctx); |
| 131 | } | 131 | } |
| 132 | if (stream.IsImmediate()) { | 132 | if (!ctx.profile.support_geometry_streams) { |
| 133 | throw NotImplementedException("Geometry streams"); | ||
| 134 | } else if (stream.IsImmediate()) { | ||
| 133 | ctx.OpEmitStreamVertex(ctx.Def(stream)); | 135 | ctx.OpEmitStreamVertex(ctx.Def(stream)); |
| 134 | } else { | 136 | } else { |
| 135 | LOG_WARNING(Shader_SPIRV, "Stream is not immediate"); | 137 | LOG_WARNING(Shader_SPIRV, "Stream is not immediate"); |
| @@ -140,7 +142,9 @@ void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { | |||
| 140 | } | 142 | } |
| 141 | 143 | ||
| 142 | void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) { | 144 | void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) { |
| 143 | if (stream.IsImmediate()) { | 145 | if (!ctx.profile.support_geometry_streams) { |
| 146 | throw NotImplementedException("Geometry streams"); | ||
| 147 | } else if (stream.IsImmediate()) { | ||
| 144 | ctx.OpEndStreamPrimitive(ctx.Def(stream)); | 148 | ctx.OpEndStreamPrimitive(ctx.Def(stream)); |
| 145 | } else { | 149 | } else { |
| 146 | LOG_WARNING(Shader_SPIRV, "Stream is not immediate"); | 150 | LOG_WARNING(Shader_SPIRV, "Stream is not immediate"); |
diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h index 7578d41cc..90e46bb1b 100644 --- a/src/shader_recompiler/profile.h +++ b/src/shader_recompiler/profile.h | |||
| @@ -44,6 +44,7 @@ struct Profile { | |||
| 44 | bool support_gl_derivative_control{}; | 44 | bool support_gl_derivative_control{}; |
| 45 | bool support_scaled_attributes{}; | 45 | bool support_scaled_attributes{}; |
| 46 | bool support_multi_viewport{}; | 46 | bool support_multi_viewport{}; |
| 47 | bool support_geometry_streams{}; | ||
| 47 | 48 | ||
| 48 | bool warp_size_potentially_larger_than_guest{}; | 49 | bool warp_size_potentially_larger_than_guest{}; |
| 49 | 50 | ||
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 6d3d933c5..ed7a5b27e 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -35,7 +35,7 @@ BufferCache<P>::BufferCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, R | |||
| 35 | const s64 min_spacing_critical = device_local_memory - 512_MiB; | 35 | const s64 min_spacing_critical = device_local_memory - 512_MiB; |
| 36 | const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD); | 36 | const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD); |
| 37 | const s64 min_vacancy_expected = (6 * mem_threshold) / 10; | 37 | const s64 min_vacancy_expected = (6 * mem_threshold) / 10; |
| 38 | const s64 min_vacancy_critical = (3 * mem_threshold) / 10; | 38 | const s64 min_vacancy_critical = (2 * mem_threshold) / 10; |
| 39 | minimum_memory = static_cast<u64>( | 39 | minimum_memory = static_cast<u64>( |
| 40 | std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected), | 40 | std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected), |
| 41 | DEFAULT_EXPECTED_MEMORY)); | 41 | DEFAULT_EXPECTED_MEMORY)); |
| @@ -1130,7 +1130,7 @@ void BufferCache<P>::UpdateVertexBuffer(u32 index) { | |||
| 1130 | channel_state->vertex_buffers[index] = NULL_BINDING; | 1130 | channel_state->vertex_buffers[index] = NULL_BINDING; |
| 1131 | return; | 1131 | return; |
| 1132 | } | 1132 | } |
| 1133 | if (!gpu_memory->IsWithinGPUAddressRange(gpu_addr_end)) { | 1133 | if (!gpu_memory->IsWithinGPUAddressRange(gpu_addr_end) || size >= 64_MiB) { |
| 1134 | size = static_cast<u32>(gpu_memory->MaxContinuousRange(gpu_addr_begin, size)); | 1134 | size = static_cast<u32>(gpu_memory->MaxContinuousRange(gpu_addr_begin, size)); |
| 1135 | } | 1135 | } |
| 1136 | const BufferId buffer_id = FindBuffer(*device_addr, size); | 1136 | const BufferId buffer_id = FindBuffer(*device_addr, size); |
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index a94e1f043..0d47b032c 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -291,7 +291,9 @@ u32 Maxwell3D::ProcessShadowRam(u32 method, u32 argument) { | |||
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | void Maxwell3D::ConsumeSinkImpl() { | 293 | void Maxwell3D::ConsumeSinkImpl() { |
| 294 | SCOPE_EXIT({ method_sink.clear(); }); | 294 | SCOPE_EXIT { |
| 295 | method_sink.clear(); | ||
| 296 | }; | ||
| 295 | const auto control = shadow_state.shadow_ram_control; | 297 | const auto control = shadow_state.shadow_ram_control; |
| 296 | if (control == Regs::ShadowRamControl::Track || | 298 | if (control == Regs::ShadowRamControl::Track || |
| 297 | control == Regs::ShadowRamControl::TrackWithFilter) { | 299 | control == Regs::ShadowRamControl::TrackWithFilter) { |
diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h index c3eda6893..2135f1f2d 100644 --- a/src/video_core/fence_manager.h +++ b/src/video_core/fence_manager.h | |||
| @@ -197,7 +197,9 @@ private: | |||
| 197 | MicroProfileOnThreadCreate(name.c_str()); | 197 | MicroProfileOnThreadCreate(name.c_str()); |
| 198 | 198 | ||
| 199 | // Cleanup | 199 | // Cleanup |
| 200 | SCOPE_EXIT({ MicroProfileOnThreadExit(); }); | 200 | SCOPE_EXIT { |
| 201 | MicroProfileOnThreadExit(); | ||
| 202 | }; | ||
| 201 | 203 | ||
| 202 | Common::SetCurrentThreadName(name.c_str()); | 204 | Common::SetCurrentThreadName(name.c_str()); |
| 203 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); | 205 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); |
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 58d8110b8..477e11457 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp | |||
| @@ -22,7 +22,9 @@ static void RunThread(std::stop_token stop_token, Core::System& system, | |||
| 22 | Tegra::Control::Scheduler& scheduler, SynchState& state) { | 22 | Tegra::Control::Scheduler& scheduler, SynchState& state) { |
| 23 | std::string name = "GPU"; | 23 | std::string name = "GPU"; |
| 24 | MicroProfileOnThreadCreate(name.c_str()); | 24 | MicroProfileOnThreadCreate(name.c_str()); |
| 25 | SCOPE_EXIT({ MicroProfileOnThreadExit(); }); | 25 | SCOPE_EXIT { |
| 26 | MicroProfileOnThreadExit(); | ||
| 27 | }; | ||
| 26 | 28 | ||
| 27 | Common::SetCurrentThreadName(name.c_str()); | 29 | Common::SetCurrentThreadName(name.c_str()); |
| 28 | Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical); | 30 | Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical); |
diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.cpp b/src/video_core/host1x/ffmpeg/ffmpeg.cpp index 96686da59..1003cd38d 100644 --- a/src/video_core/host1x/ffmpeg/ffmpeg.cpp +++ b/src/video_core/host1x/ffmpeg/ffmpeg.cpp | |||
| @@ -273,10 +273,10 @@ DeinterlaceFilter::DeinterlaceFilter(const Frame& frame) { | |||
| 273 | const AVFilter* buffer_sink = avfilter_get_by_name("buffersink"); | 273 | const AVFilter* buffer_sink = avfilter_get_by_name("buffersink"); |
| 274 | AVFilterInOut* inputs = avfilter_inout_alloc(); | 274 | AVFilterInOut* inputs = avfilter_inout_alloc(); |
| 275 | AVFilterInOut* outputs = avfilter_inout_alloc(); | 275 | AVFilterInOut* outputs = avfilter_inout_alloc(); |
| 276 | SCOPE_EXIT({ | 276 | SCOPE_EXIT { |
| 277 | avfilter_inout_free(&inputs); | 277 | avfilter_inout_free(&inputs); |
| 278 | avfilter_inout_free(&outputs); | 278 | avfilter_inout_free(&outputs); |
| 279 | }); | 279 | }; |
| 280 | 280 | ||
| 281 | // Don't know how to get the accurate time_base but it doesn't matter for yadif filter | 281 | // Don't know how to get the accurate time_base but it doesn't matter for yadif filter |
| 282 | // so just use 1/1 to make buffer filter happy | 282 | // so just use 1/1 to make buffer filter happy |
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp index 46e853e04..fb529f88b 100644 --- a/src/video_core/macro/macro_hle.cpp +++ b/src/video_core/macro/macro_hle.cpp | |||
| @@ -92,12 +92,12 @@ public: | |||
| 92 | 92 | ||
| 93 | private: | 93 | private: |
| 94 | void Fallback(const std::vector<u32>& parameters) { | 94 | void Fallback(const std::vector<u32>& parameters) { |
| 95 | SCOPE_EXIT({ | 95 | SCOPE_EXIT { |
| 96 | if (extended) { | 96 | if (extended) { |
| 97 | maxwell3d.engine_state = Maxwell3D::EngineHint::None; | 97 | maxwell3d.engine_state = Maxwell3D::EngineHint::None; |
| 98 | maxwell3d.replace_table.clear(); | 98 | maxwell3d.replace_table.clear(); |
| 99 | } | 99 | } |
| 100 | }); | 100 | }; |
| 101 | maxwell3d.RefreshParameters(); | 101 | maxwell3d.RefreshParameters(); |
| 102 | const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]); | 102 | const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]); |
| 103 | 103 | ||
| @@ -281,12 +281,12 @@ public: | |||
| 281 | 281 | ||
| 282 | private: | 282 | private: |
| 283 | void Fallback(const std::vector<u32>& parameters) { | 283 | void Fallback(const std::vector<u32>& parameters) { |
| 284 | SCOPE_EXIT({ | 284 | SCOPE_EXIT { |
| 285 | // Clean everything. | 285 | // Clean everything. |
| 286 | maxwell3d.regs.vertex_id_base = 0x0; | 286 | maxwell3d.regs.vertex_id_base = 0x0; |
| 287 | maxwell3d.engine_state = Maxwell3D::EngineHint::None; | 287 | maxwell3d.engine_state = Maxwell3D::EngineHint::None; |
| 288 | maxwell3d.replace_table.clear(); | 288 | maxwell3d.replace_table.clear(); |
| 289 | }); | 289 | }; |
| 290 | maxwell3d.RefreshParameters(); | 290 | maxwell3d.RefreshParameters(); |
| 291 | const u32 start_indirect = parameters[0]; | 291 | const u32 start_indirect = parameters[0]; |
| 292 | const u32 end_indirect = parameters[1]; | 292 | const u32 end_indirect = parameters[1]; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b42fb110c..16af8e6bd 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -230,7 +230,9 @@ template <typename Func> | |||
| 230 | void RasterizerOpenGL::PrepareDraw(bool is_indexed, Func&& draw_func) { | 230 | void RasterizerOpenGL::PrepareDraw(bool is_indexed, Func&& draw_func) { |
| 231 | MICROPROFILE_SCOPE(OpenGL_Drawing); | 231 | MICROPROFILE_SCOPE(OpenGL_Drawing); |
| 232 | 232 | ||
| 233 | SCOPE_EXIT({ gpu.TickWork(); }); | 233 | SCOPE_EXIT { |
| 234 | gpu.TickWork(); | ||
| 235 | }; | ||
| 234 | gpu_memory->FlushCaching(); | 236 | gpu_memory->FlushCaching(); |
| 235 | 237 | ||
| 236 | GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()}; | 238 | GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()}; |
| @@ -355,7 +357,9 @@ void RasterizerOpenGL::DrawIndirect() { | |||
| 355 | void RasterizerOpenGL::DrawTexture() { | 357 | void RasterizerOpenGL::DrawTexture() { |
| 356 | MICROPROFILE_SCOPE(OpenGL_Drawing); | 358 | MICROPROFILE_SCOPE(OpenGL_Drawing); |
| 357 | 359 | ||
| 358 | SCOPE_EXIT({ gpu.TickWork(); }); | 360 | SCOPE_EXIT { |
| 361 | gpu.TickWork(); | ||
| 362 | }; | ||
| 359 | 363 | ||
| 360 | texture_cache.SynchronizeGraphicsDescriptors(); | 364 | texture_cache.SynchronizeGraphicsDescriptors(); |
| 361 | texture_cache.UpdateRenderTargets(false); | 365 | texture_cache.UpdateRenderTargets(false); |
diff --git a/src/video_core/renderer_vulkan/present/layer.cpp b/src/video_core/renderer_vulkan/present/layer.cpp index 3847a9a13..4e41afe5b 100644 --- a/src/video_core/renderer_vulkan/present/layer.cpp +++ b/src/video_core/renderer_vulkan/present/layer.cpp | |||
| @@ -82,7 +82,9 @@ void Layer::ConfigureDraw(PresentPushConstants* out_push_constants, | |||
| 82 | // Finish any pending renderpass | 82 | // Finish any pending renderpass |
| 83 | scheduler.RequestOutsideRenderPassOperationContext(); | 83 | scheduler.RequestOutsideRenderPassOperationContext(); |
| 84 | scheduler.Wait(resource_ticks[image_index]); | 84 | scheduler.Wait(resource_ticks[image_index]); |
| 85 | SCOPE_EXIT({ resource_ticks[image_index] = scheduler.CurrentTick(); }); | 85 | SCOPE_EXIT { |
| 86 | resource_ticks[image_index] = scheduler.CurrentTick(); | ||
| 87 | }; | ||
| 86 | 88 | ||
| 87 | if (!use_accelerated) { | 89 | if (!use_accelerated) { |
| 88 | UpdateRawImage(framebuffer, image_index); | 90 | UpdateRawImage(framebuffer, image_index); |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index d50417116..c553f5b3d 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp | |||
| @@ -144,7 +144,9 @@ void RendererVulkan::Composite(std::span<const Tegra::FramebufferConfig> framebu | |||
| 144 | return; | 144 | return; |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | SCOPE_EXIT({ render_window.OnFrameDisplayed(); }); | 147 | SCOPE_EXIT { |
| 148 | render_window.OnFrameDisplayed(); | ||
| 149 | }; | ||
| 148 | 150 | ||
| 149 | RenderAppletCaptureLayer(framebuffers); | 151 | RenderAppletCaptureLayer(framebuffers); |
| 150 | 152 | ||
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 20f7a9702..d34b585d6 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -352,6 +352,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, | |||
| 352 | .support_native_ndc = device.IsExtDepthClipControlSupported(), | 352 | .support_native_ndc = device.IsExtDepthClipControlSupported(), |
| 353 | .support_scaled_attributes = !device.MustEmulateScaledFormats(), | 353 | .support_scaled_attributes = !device.MustEmulateScaledFormats(), |
| 354 | .support_multi_viewport = device.SupportsMultiViewport(), | 354 | .support_multi_viewport = device.SupportsMultiViewport(), |
| 355 | .support_geometry_streams = device.AreTransformFeedbackGeometryStreamsSupported(), | ||
| 355 | 356 | ||
| 356 | .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), | 357 | .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), |
| 357 | 358 | ||
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index aa0a027bb..74f9f099e 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -196,7 +196,9 @@ template <typename Func> | |||
| 196 | void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) { | 196 | void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) { |
| 197 | MICROPROFILE_SCOPE(Vulkan_Drawing); | 197 | MICROPROFILE_SCOPE(Vulkan_Drawing); |
| 198 | 198 | ||
| 199 | SCOPE_EXIT({ gpu.TickWork(); }); | 199 | SCOPE_EXIT { |
| 200 | gpu.TickWork(); | ||
| 201 | }; | ||
| 200 | FlushWork(); | 202 | FlushWork(); |
| 201 | gpu_memory->FlushCaching(); | 203 | gpu_memory->FlushCaching(); |
| 202 | 204 | ||
| @@ -288,7 +290,9 @@ void RasterizerVulkan::DrawIndirect() { | |||
| 288 | void RasterizerVulkan::DrawTexture() { | 290 | void RasterizerVulkan::DrawTexture() { |
| 289 | MICROPROFILE_SCOPE(Vulkan_Drawing); | 291 | MICROPROFILE_SCOPE(Vulkan_Drawing); |
| 290 | 292 | ||
| 291 | SCOPE_EXIT({ gpu.TickWork(); }); | 293 | SCOPE_EXIT { |
| 294 | gpu.TickWork(); | ||
| 295 | }; | ||
| 292 | FlushWork(); | 296 | FlushWork(); |
| 293 | 297 | ||
| 294 | query_cache.NotifySegment(true); | 298 | query_cache.NotifySegment(true); |
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 5b3c7aa5a..9055b1b92 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include "common/common_types.h" | 4 | #include "common/common_types.h" |
| 5 | #include "common/math_util.h" | 5 | #include "common/math_util.h" |
| 6 | #include "common/settings.h" | ||
| 6 | #include "video_core/surface.h" | 7 | #include "video_core/surface.h" |
| 7 | 8 | ||
| 8 | namespace VideoCore::Surface { | 9 | namespace VideoCore::Surface { |
| @@ -400,11 +401,20 @@ std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) { | |||
| 400 | return {DefaultBlockWidth(format), DefaultBlockHeight(format)}; | 401 | return {DefaultBlockWidth(format), DefaultBlockHeight(format)}; |
| 401 | } | 402 | } |
| 402 | 403 | ||
| 403 | u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format) { | 404 | u64 TranscodedAstcSize(u64 base_size, PixelFormat format) { |
| 404 | constexpr u64 RGBA8_PIXEL_SIZE = 4; | 405 | constexpr u64 RGBA8_PIXEL_SIZE = 4; |
| 405 | const u64 base_block_size = static_cast<u64>(DefaultBlockWidth(format)) * | 406 | const u64 base_block_size = static_cast<u64>(DefaultBlockWidth(format)) * |
| 406 | static_cast<u64>(DefaultBlockHeight(format)) * RGBA8_PIXEL_SIZE; | 407 | static_cast<u64>(DefaultBlockHeight(format)) * RGBA8_PIXEL_SIZE; |
| 407 | return (base_size * base_block_size) / BytesPerBlock(format); | 408 | const u64 uncompressed_size = (base_size * base_block_size) / BytesPerBlock(format); |
| 409 | |||
| 410 | switch (Settings::values.astc_recompression.GetValue()) { | ||
| 411 | case Settings::AstcRecompression::Bc1: | ||
| 412 | return uncompressed_size / 8; | ||
| 413 | case Settings::AstcRecompression::Bc3: | ||
| 414 | return uncompressed_size / 4; | ||
| 415 | default: | ||
| 416 | return uncompressed_size; | ||
| 417 | } | ||
| 408 | } | 418 | } |
| 409 | 419 | ||
| 410 | } // namespace VideoCore::Surface | 420 | } // namespace VideoCore::Surface |
diff --git a/src/video_core/surface.h b/src/video_core/surface.h index a5e8e2f62..ec9cd2fbf 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h | |||
| @@ -517,6 +517,6 @@ size_t PixelComponentSizeBitsInteger(PixelFormat format); | |||
| 517 | 517 | ||
| 518 | std::pair<u32, u32> GetASTCBlockSize(PixelFormat format); | 518 | std::pair<u32, u32> GetASTCBlockSize(PixelFormat format); |
| 519 | 519 | ||
| 520 | u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format); | 520 | u64 TranscodedAstcSize(u64 base_size, PixelFormat format); |
| 521 | 521 | ||
| 522 | } // namespace VideoCore::Surface | 522 | } // namespace VideoCore::Surface |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 01c3561c9..53b4876f2 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -55,7 +55,7 @@ TextureCache<P>::TextureCache(Runtime& runtime_, Tegra::MaxwellDeviceMemoryManag | |||
| 55 | const s64 min_spacing_critical = device_local_memory - 512_MiB; | 55 | const s64 min_spacing_critical = device_local_memory - 512_MiB; |
| 56 | const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD); | 56 | const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD); |
| 57 | const s64 min_vacancy_expected = (6 * mem_threshold) / 10; | 57 | const s64 min_vacancy_expected = (6 * mem_threshold) / 10; |
| 58 | const s64 min_vacancy_critical = (3 * mem_threshold) / 10; | 58 | const s64 min_vacancy_critical = (2 * mem_threshold) / 10; |
| 59 | expected_memory = static_cast<u64>( | 59 | expected_memory = static_cast<u64>( |
| 60 | std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected), | 60 | std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected), |
| 61 | DEFAULT_EXPECTED_MEMORY)); | 61 | DEFAULT_EXPECTED_MEMORY)); |
| @@ -1979,7 +1979,7 @@ void TextureCache<P>::RegisterImage(ImageId image_id) { | |||
| 1979 | if ((IsPixelFormatASTC(image.info.format) && | 1979 | if ((IsPixelFormatASTC(image.info.format) && |
| 1980 | True(image.flags & ImageFlagBits::AcceleratedUpload)) || | 1980 | True(image.flags & ImageFlagBits::AcceleratedUpload)) || |
| 1981 | True(image.flags & ImageFlagBits::Converted)) { | 1981 | True(image.flags & ImageFlagBits::Converted)) { |
| 1982 | tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); | 1982 | tentative_size = TranscodedAstcSize(tentative_size, image.info.format); |
| 1983 | } | 1983 | } |
| 1984 | total_used_memory += Common::AlignUp(tentative_size, 1024); | 1984 | total_used_memory += Common::AlignUp(tentative_size, 1024); |
| 1985 | image.lru_index = lru_cache.Insert(image_id, frame_tick); | 1985 | image.lru_index = lru_cache.Insert(image_id, frame_tick); |
| @@ -2149,7 +2149,7 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) { | |||
| 2149 | if ((IsPixelFormatASTC(image.info.format) && | 2149 | if ((IsPixelFormatASTC(image.info.format) && |
| 2150 | True(image.flags & ImageFlagBits::AcceleratedUpload)) || | 2150 | True(image.flags & ImageFlagBits::AcceleratedUpload)) || |
| 2151 | True(image.flags & ImageFlagBits::Converted)) { | 2151 | True(image.flags & ImageFlagBits::Converted)) { |
| 2152 | tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); | 2152 | tentative_size = TranscodedAstcSize(tentative_size, image.info.format); |
| 2153 | } | 2153 | } |
| 2154 | total_used_memory -= Common::AlignUp(tentative_size, 1024); | 2154 | total_used_memory -= Common::AlignUp(tentative_size, 1024); |
| 2155 | const GPUVAddr gpu_addr = image.gpu_addr; | 2155 | const GPUVAddr gpu_addr = image.gpu_addr; |
diff --git a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp index 5fa0d9620..f41c3e506 100644 --- a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp +++ b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp | |||
| @@ -116,7 +116,9 @@ void NsightAftermathTracker::OnGpuCrashDumpCallback(const void* gpu_crash_dump, | |||
| 116 | LOG_ERROR(Render_Vulkan, "Failed to create decoder"); | 116 | LOG_ERROR(Render_Vulkan, "Failed to create decoder"); |
| 117 | return; | 117 | return; |
| 118 | } | 118 | } |
| 119 | SCOPE_EXIT({ GFSDK_Aftermath_GpuCrashDump_DestroyDecoder(decoder); }); | 119 | SCOPE_EXIT { |
| 120 | GFSDK_Aftermath_GpuCrashDump_DestroyDecoder(decoder); | ||
| 121 | }; | ||
| 120 | 122 | ||
| 121 | u32 json_size = 0; | 123 | u32 json_size = 0; |
| 122 | if (!GFSDK_Aftermath_SUCCEED(GFSDK_Aftermath_GpuCrashDump_GenerateJSON( | 124 | if (!GFSDK_Aftermath_SUCCEED(GFSDK_Aftermath_GpuCrashDump_GenerateJSON( |
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index a2ec26697..e3abe8ddf 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h | |||
| @@ -499,6 +499,11 @@ public: | |||
| 499 | return extensions.transform_feedback; | 499 | return extensions.transform_feedback; |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | /// Returns true if the device supports VK_EXT_transform_feedback properly. | ||
| 503 | bool AreTransformFeedbackGeometryStreamsSupported() const { | ||
| 504 | return features.transform_feedback.geometryStreams; | ||
| 505 | } | ||
| 506 | |||
| 502 | /// Returns true if the device supports VK_EXT_custom_border_color. | 507 | /// Returns true if the device supports VK_EXT_custom_border_color. |
| 503 | bool IsExtCustomBorderColorSupported() const { | 508 | bool IsExtCustomBorderColorSupported() const { |
| 504 | return extensions.custom_border_color; | 509 | return extensions.custom_border_color; |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 0d16bfd65..b2ae3db52 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -646,10 +646,10 @@ void GMainWindow::AmiiboSettingsShowDialog(const Core::Frontend::CabinetParamete | |||
| 646 | std::shared_ptr<Service::NFC::NfcDevice> nfp_device) { | 646 | std::shared_ptr<Service::NFC::NfcDevice> nfp_device) { |
| 647 | cabinet_applet = | 647 | cabinet_applet = |
| 648 | new QtAmiiboSettingsDialog(this, parameters, input_subsystem.get(), nfp_device); | 648 | new QtAmiiboSettingsDialog(this, parameters, input_subsystem.get(), nfp_device); |
| 649 | SCOPE_EXIT({ | 649 | SCOPE_EXIT { |
| 650 | cabinet_applet->deleteLater(); | 650 | cabinet_applet->deleteLater(); |
| 651 | cabinet_applet = nullptr; | 651 | cabinet_applet = nullptr; |
| 652 | }); | 652 | }; |
| 653 | 653 | ||
| 654 | cabinet_applet->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | | 654 | cabinet_applet->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | |
| 655 | Qt::WindowTitleHint | Qt::WindowSystemMenuHint); | 655 | Qt::WindowTitleHint | Qt::WindowSystemMenuHint); |
| @@ -673,10 +673,10 @@ void GMainWindow::ControllerSelectorReconfigureControllers( | |||
| 673 | const Core::Frontend::ControllerParameters& parameters) { | 673 | const Core::Frontend::ControllerParameters& parameters) { |
| 674 | controller_applet = | 674 | controller_applet = |
| 675 | new QtControllerSelectorDialog(this, parameters, input_subsystem.get(), *system); | 675 | new QtControllerSelectorDialog(this, parameters, input_subsystem.get(), *system); |
| 676 | SCOPE_EXIT({ | 676 | SCOPE_EXIT { |
| 677 | controller_applet->deleteLater(); | 677 | controller_applet->deleteLater(); |
| 678 | controller_applet = nullptr; | 678 | controller_applet = nullptr; |
| 679 | }); | 679 | }; |
| 680 | 680 | ||
| 681 | controller_applet->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | | 681 | controller_applet->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | |
| 682 | Qt::WindowStaysOnTopHint | Qt::WindowTitleHint | | 682 | Qt::WindowStaysOnTopHint | Qt::WindowTitleHint | |
| @@ -703,10 +703,10 @@ void GMainWindow::ControllerSelectorRequestExit() { | |||
| 703 | void GMainWindow::ProfileSelectorSelectProfile( | 703 | void GMainWindow::ProfileSelectorSelectProfile( |
| 704 | const Core::Frontend::ProfileSelectParameters& parameters) { | 704 | const Core::Frontend::ProfileSelectParameters& parameters) { |
| 705 | profile_select_applet = new QtProfileSelectionDialog(*system, this, parameters); | 705 | profile_select_applet = new QtProfileSelectionDialog(*system, this, parameters); |
| 706 | SCOPE_EXIT({ | 706 | SCOPE_EXIT { |
| 707 | profile_select_applet->deleteLater(); | 707 | profile_select_applet->deleteLater(); |
| 708 | profile_select_applet = nullptr; | 708 | profile_select_applet = nullptr; |
| 709 | }); | 709 | }; |
| 710 | 710 | ||
| 711 | profile_select_applet->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | | 711 | profile_select_applet->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | |
| 712 | Qt::WindowStaysOnTopHint | Qt::WindowTitleHint | | 712 | Qt::WindowStaysOnTopHint | Qt::WindowTitleHint | |
| @@ -1604,6 +1604,7 @@ void GMainWindow::ConnectMenuEvents() { | |||
| 1604 | connect_menu(ui->action_Open_yuzu_Folder, &GMainWindow::OnOpenYuzuFolder); | 1604 | connect_menu(ui->action_Open_yuzu_Folder, &GMainWindow::OnOpenYuzuFolder); |
| 1605 | connect_menu(ui->action_Verify_installed_contents, &GMainWindow::OnVerifyInstalledContents); | 1605 | connect_menu(ui->action_Verify_installed_contents, &GMainWindow::OnVerifyInstalledContents); |
| 1606 | connect_menu(ui->action_Install_Firmware, &GMainWindow::OnInstallFirmware); | 1606 | connect_menu(ui->action_Install_Firmware, &GMainWindow::OnInstallFirmware); |
| 1607 | connect_menu(ui->action_Install_Keys, &GMainWindow::OnInstallDecryptionKeys); | ||
| 1607 | connect_menu(ui->action_About, &GMainWindow::OnAbout); | 1608 | connect_menu(ui->action_About, &GMainWindow::OnAbout); |
| 1608 | } | 1609 | } |
| 1609 | 1610 | ||
| @@ -1633,6 +1634,7 @@ void GMainWindow::UpdateMenuState() { | |||
| 1633 | } | 1634 | } |
| 1634 | 1635 | ||
| 1635 | ui->action_Install_Firmware->setEnabled(!emulation_running); | 1636 | ui->action_Install_Firmware->setEnabled(!emulation_running); |
| 1637 | ui->action_Install_Keys->setEnabled(!emulation_running); | ||
| 1636 | 1638 | ||
| 1637 | for (QAction* action : applet_actions) { | 1639 | for (QAction* action : applet_actions) { |
| 1638 | action->setEnabled(is_firmware_available && !emulation_running); | 1640 | action->setEnabled(is_firmware_available && !emulation_running); |
| @@ -2885,17 +2887,19 @@ bool GMainWindow::CreateShortcutLink(const std::filesystem::path& shortcut_path, | |||
| 2885 | LOG_ERROR(Frontend, "CoInitialize failed"); | 2887 | LOG_ERROR(Frontend, "CoInitialize failed"); |
| 2886 | return false; | 2888 | return false; |
| 2887 | } | 2889 | } |
| 2888 | SCOPE_EXIT({ CoUninitialize(); }); | 2890 | SCOPE_EXIT { |
| 2891 | CoUninitialize(); | ||
| 2892 | }; | ||
| 2889 | IShellLinkW* ps1 = nullptr; | 2893 | IShellLinkW* ps1 = nullptr; |
| 2890 | IPersistFile* persist_file = nullptr; | 2894 | IPersistFile* persist_file = nullptr; |
| 2891 | SCOPE_EXIT({ | 2895 | SCOPE_EXIT { |
| 2892 | if (persist_file != nullptr) { | 2896 | if (persist_file != nullptr) { |
| 2893 | persist_file->Release(); | 2897 | persist_file->Release(); |
| 2894 | } | 2898 | } |
| 2895 | if (ps1 != nullptr) { | 2899 | if (ps1 != nullptr) { |
| 2896 | ps1->Release(); | 2900 | ps1->Release(); |
| 2897 | } | 2901 | } |
| 2898 | }); | 2902 | }; |
| 2899 | HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW, | 2903 | HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW, |
| 2900 | reinterpret_cast<void**>(&ps1)); | 2904 | reinterpret_cast<void**>(&ps1)); |
| 2901 | if (FAILED(hres)) { | 2905 | if (FAILED(hres)) { |
| @@ -3520,10 +3524,10 @@ void GMainWindow::OnSaveConfig() { | |||
| 3520 | void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) { | 3524 | void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) { |
| 3521 | error_applet = new OverlayDialog(render_window, *system, error_code, error_text, QString{}, | 3525 | error_applet = new OverlayDialog(render_window, *system, error_code, error_text, QString{}, |
| 3522 | tr("OK"), Qt::AlignLeft | Qt::AlignVCenter); | 3526 | tr("OK"), Qt::AlignLeft | Qt::AlignVCenter); |
| 3523 | SCOPE_EXIT({ | 3527 | SCOPE_EXIT { |
| 3524 | error_applet->deleteLater(); | 3528 | error_applet->deleteLater(); |
| 3525 | error_applet = nullptr; | 3529 | error_applet = nullptr; |
| 3526 | }); | 3530 | }; |
| 3527 | error_applet->exec(); | 3531 | error_applet->exec(); |
| 3528 | 3532 | ||
| 3529 | emit ErrorDisplayFinished(); | 3533 | emit ErrorDisplayFinished(); |
| @@ -4167,9 +4171,8 @@ void GMainWindow::OnInstallFirmware() { | |||
| 4167 | return; | 4171 | return; |
| 4168 | } | 4172 | } |
| 4169 | 4173 | ||
| 4170 | QString firmware_source_location = | 4174 | const QString firmware_source_location = QFileDialog::getExistingDirectory( |
| 4171 | QFileDialog::getExistingDirectory(this, tr("Select Dumped Firmware Source Location"), | 4175 | this, tr("Select Dumped Firmware Source Location"), {}, QFileDialog::ShowDirsOnly); |
| 4172 | QString::fromStdString(""), QFileDialog::ShowDirsOnly); | ||
| 4173 | if (firmware_source_location.isEmpty()) { | 4176 | if (firmware_source_location.isEmpty()) { |
| 4174 | return; | 4177 | return; |
| 4175 | } | 4178 | } |
| @@ -4200,8 +4203,9 @@ void GMainWindow::OnInstallFirmware() { | |||
| 4200 | std::vector<std::filesystem::path> out; | 4203 | std::vector<std::filesystem::path> out; |
| 4201 | const Common::FS::DirEntryCallable callback = | 4204 | const Common::FS::DirEntryCallable callback = |
| 4202 | [&out](const std::filesystem::directory_entry& entry) { | 4205 | [&out](const std::filesystem::directory_entry& entry) { |
| 4203 | if (entry.path().has_extension() && entry.path().extension() == ".nca") | 4206 | if (entry.path().has_extension() && entry.path().extension() == ".nca") { |
| 4204 | out.emplace_back(entry.path()); | 4207 | out.emplace_back(entry.path()); |
| 4208 | } | ||
| 4205 | 4209 | ||
| 4206 | return true; | 4210 | return true; |
| 4207 | }; | 4211 | }; |
| @@ -4233,7 +4237,6 @@ void GMainWindow::OnInstallFirmware() { | |||
| 4233 | auto firmware_vdir = sysnand_content_vdir->GetDirectoryRelative("registered"); | 4237 | auto firmware_vdir = sysnand_content_vdir->GetDirectoryRelative("registered"); |
| 4234 | 4238 | ||
| 4235 | bool success = true; | 4239 | bool success = true; |
| 4236 | bool cancelled = false; | ||
| 4237 | int i = 0; | 4240 | int i = 0; |
| 4238 | for (const auto& firmware_src_path : out) { | 4241 | for (const auto& firmware_src_path : out) { |
| 4239 | i++; | 4242 | i++; |
| @@ -4248,24 +4251,22 @@ void GMainWindow::OnInstallFirmware() { | |||
| 4248 | success = false; | 4251 | success = false; |
| 4249 | } | 4252 | } |
| 4250 | 4253 | ||
| 4251 | if (QtProgressCallback(100, 20 + (int)(((float)(i) / (float)out.size()) * 70.0))) { | 4254 | if (QtProgressCallback( |
| 4252 | success = false; | 4255 | 100, 20 + static_cast<int>(((i) / static_cast<float>(out.size())) * 70.0))) { |
| 4253 | cancelled = true; | 4256 | progress.close(); |
| 4254 | break; | 4257 | QMessageBox::warning( |
| 4258 | this, tr("Firmware install failed"), | ||
| 4259 | tr("Firmware installation cancelled, firmware may be in bad state, " | ||
| 4260 | "restart yuzu or re-install firmware.")); | ||
| 4261 | return; | ||
| 4255 | } | 4262 | } |
| 4256 | } | 4263 | } |
| 4257 | 4264 | ||
| 4258 | if (!success && !cancelled) { | 4265 | if (!success) { |
| 4259 | progress.close(); | 4266 | progress.close(); |
| 4260 | QMessageBox::critical(this, tr("Firmware install failed"), | 4267 | QMessageBox::critical(this, tr("Firmware install failed"), |
| 4261 | tr("One or more firmware files failed to copy into NAND.")); | 4268 | tr("One or more firmware files failed to copy into NAND.")); |
| 4262 | return; | 4269 | return; |
| 4263 | } else if (cancelled) { | ||
| 4264 | progress.close(); | ||
| 4265 | QMessageBox::warning(this, tr("Firmware install failed"), | ||
| 4266 | tr("Firmware installation cancelled, firmware may be in bad state, " | ||
| 4267 | "restart yuzu or re-install firmware.")); | ||
| 4268 | return; | ||
| 4269 | } | 4270 | } |
| 4270 | 4271 | ||
| 4271 | // Re-scan VFS for the newly placed firmware files. | 4272 | // Re-scan VFS for the newly placed firmware files. |
| @@ -4293,6 +4294,84 @@ void GMainWindow::OnInstallFirmware() { | |||
| 4293 | OnCheckFirmwareDecryption(); | 4294 | OnCheckFirmwareDecryption(); |
| 4294 | } | 4295 | } |
| 4295 | 4296 | ||
| 4297 | void GMainWindow::OnInstallDecryptionKeys() { | ||
| 4298 | // Don't do this while emulation is running. | ||
| 4299 | if (emu_thread != nullptr && emu_thread->IsRunning()) { | ||
| 4300 | return; | ||
| 4301 | } | ||
| 4302 | |||
| 4303 | const QString key_source_location = QFileDialog::getOpenFileName( | ||
| 4304 | this, tr("Select Dumped Keys Location"), {}, QStringLiteral("prod.keys (prod.keys)"), {}, | ||
| 4305 | QFileDialog::ReadOnly); | ||
| 4306 | if (key_source_location.isEmpty()) { | ||
| 4307 | return; | ||
| 4308 | } | ||
| 4309 | |||
| 4310 | // Verify that it contains prod.keys, title.keys and optionally, key_retail.bin | ||
| 4311 | LOG_INFO(Frontend, "Installing key files from {}", key_source_location.toStdString()); | ||
| 4312 | |||
| 4313 | const std::filesystem::path prod_key_path = key_source_location.toStdString(); | ||
| 4314 | const std::filesystem::path key_source_path = prod_key_path.parent_path(); | ||
| 4315 | if (!Common::FS::IsDir(key_source_path)) { | ||
| 4316 | return; | ||
| 4317 | } | ||
| 4318 | |||
| 4319 | bool prod_keys_found = false; | ||
| 4320 | std::vector<std::filesystem::path> source_key_files; | ||
| 4321 | |||
| 4322 | if (Common::FS::Exists(prod_key_path)) { | ||
| 4323 | prod_keys_found = true; | ||
| 4324 | source_key_files.emplace_back(prod_key_path); | ||
| 4325 | } | ||
| 4326 | |||
| 4327 | if (Common::FS::Exists(key_source_path / "title.keys")) { | ||
| 4328 | source_key_files.emplace_back(key_source_path / "title.keys"); | ||
| 4329 | } | ||
| 4330 | |||
| 4331 | if (Common::FS::Exists(key_source_path / "key_retail.bin")) { | ||
| 4332 | source_key_files.emplace_back(key_source_path / "key_retail.bin"); | ||
| 4333 | } | ||
| 4334 | |||
| 4335 | // There should be at least prod.keys. | ||
| 4336 | if (source_key_files.empty() || !prod_keys_found) { | ||
| 4337 | QMessageBox::warning(this, tr("Decryption Keys install failed"), | ||
| 4338 | tr("prod.keys is a required decryption key file.")); | ||
| 4339 | return; | ||
| 4340 | } | ||
| 4341 | |||
| 4342 | const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); | ||
| 4343 | for (auto key_file : source_key_files) { | ||
| 4344 | std::filesystem::path destination_key_file = yuzu_keys_dir / key_file.filename(); | ||
| 4345 | if (!std::filesystem::copy_file(key_file, destination_key_file, | ||
| 4346 | std::filesystem::copy_options::overwrite_existing)) { | ||
| 4347 | LOG_ERROR(Frontend, "Failed to copy file {} to {}", key_file.string(), | ||
| 4348 | destination_key_file.string()); | ||
| 4349 | QMessageBox::critical(this, tr("Decryption Keys install failed"), | ||
| 4350 | tr("One or more keys failed to copy.")); | ||
| 4351 | return; | ||
| 4352 | } | ||
| 4353 | } | ||
| 4354 | |||
| 4355 | // Reinitialize the key manager, re-read the vfs (for update/dlc files), | ||
| 4356 | // and re-populate the game list in the UI if the user has already added | ||
| 4357 | // game folders. | ||
| 4358 | Core::Crypto::KeyManager::Instance().ReloadKeys(); | ||
| 4359 | system->GetFileSystemController().CreateFactories(*vfs); | ||
| 4360 | game_list->PopulateAsync(UISettings::values.game_dirs); | ||
| 4361 | |||
| 4362 | if (ContentManager::AreKeysPresent()) { | ||
| 4363 | QMessageBox::information(this, tr("Decryption Keys install succeeded"), | ||
| 4364 | tr("Decryption Keys were successfully installed")); | ||
| 4365 | } else { | ||
| 4366 | QMessageBox::critical( | ||
| 4367 | this, tr("Decryption Keys install failed"), | ||
| 4368 | tr("Decryption Keys failed to initialize. Check that your dumping tools are " | ||
| 4369 | "up to date and re-dump keys.")); | ||
| 4370 | } | ||
| 4371 | |||
| 4372 | OnCheckFirmwareDecryption(); | ||
| 4373 | } | ||
| 4374 | |||
| 4296 | void GMainWindow::OnAbout() { | 4375 | void GMainWindow::OnAbout() { |
| 4297 | AboutDialog aboutDialog(this); | 4376 | AboutDialog aboutDialog(this); |
| 4298 | aboutDialog.exec(); | 4377 | aboutDialog.exec(); |
| @@ -5192,7 +5271,9 @@ int main(int argc, char* argv[]) { | |||
| 5192 | 5271 | ||
| 5193 | Common::DetachedTasks detached_tasks; | 5272 | Common::DetachedTasks detached_tasks; |
| 5194 | MicroProfileOnThreadCreate("Frontend"); | 5273 | MicroProfileOnThreadCreate("Frontend"); |
| 5195 | SCOPE_EXIT({ MicroProfileShutdown(); }); | 5274 | SCOPE_EXIT { |
| 5275 | MicroProfileShutdown(); | ||
| 5276 | }; | ||
| 5196 | 5277 | ||
| 5197 | Common::ConfigureNvidiaEnvironmentFlags(); | 5278 | Common::ConfigureNvidiaEnvironmentFlags(); |
| 5198 | 5279 | ||
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 1f0e35c67..fce643f3f 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -381,6 +381,7 @@ private slots: | |||
| 381 | void OnOpenYuzuFolder(); | 381 | void OnOpenYuzuFolder(); |
| 382 | void OnVerifyInstalledContents(); | 382 | void OnVerifyInstalledContents(); |
| 383 | void OnInstallFirmware(); | 383 | void OnInstallFirmware(); |
| 384 | void OnInstallDecryptionKeys(); | ||
| 384 | void OnAbout(); | 385 | void OnAbout(); |
| 385 | void OnToggleFilterBar(); | 386 | void OnToggleFilterBar(); |
| 386 | void OnToggleStatusBar(); | 387 | void OnToggleStatusBar(); |
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index 6ff444a22..85dc1f2f6 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui | |||
| @@ -165,8 +165,9 @@ | |||
| 165 | <addaction name="separator"/> | 165 | <addaction name="separator"/> |
| 166 | <addaction name="action_Configure_Tas"/> | 166 | <addaction name="action_Configure_Tas"/> |
| 167 | </widget> | 167 | </widget> |
| 168 | <addaction name="action_Verify_installed_contents"/> | 168 | <addaction name="action_Install_Keys"/> |
| 169 | <addaction name="action_Install_Firmware"/> | 169 | <addaction name="action_Install_Firmware"/> |
| 170 | <addaction name="action_Verify_installed_contents"/> | ||
| 170 | <addaction name="separator"/> | 171 | <addaction name="separator"/> |
| 171 | <addaction name="menu_cabinet_applet"/> | 172 | <addaction name="menu_cabinet_applet"/> |
| 172 | <addaction name="action_Load_Album"/> | 173 | <addaction name="action_Load_Album"/> |
| @@ -469,6 +470,11 @@ | |||
| 469 | <string>Install Firmware</string> | 470 | <string>Install Firmware</string> |
| 470 | </property> | 471 | </property> |
| 471 | </action> | 472 | </action> |
| 473 | <action name="action_Install_Keys"> | ||
| 474 | <property name="text"> | ||
| 475 | <string>Install Decryption Keys</string> | ||
| 476 | </property> | ||
| 477 | </action> | ||
| 472 | </widget> | 478 | </widget> |
| 473 | <resources> | 479 | <resources> |
| 474 | <include location="yuzu.qrc"/> | 480 | <include location="yuzu.qrc"/> |
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 3b321dad1..8a8cdbc44 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -327,7 +327,9 @@ int main(int argc, char** argv) { | |||
| 327 | #endif | 327 | #endif |
| 328 | 328 | ||
| 329 | MicroProfileOnThreadCreate("EmuThread"); | 329 | MicroProfileOnThreadCreate("EmuThread"); |
| 330 | SCOPE_EXIT({ MicroProfileShutdown(); }); | 330 | SCOPE_EXIT { |
| 331 | MicroProfileShutdown(); | ||
| 332 | }; | ||
| 331 | 333 | ||
| 332 | Common::ConfigureNvidiaEnvironmentFlags(); | 334 | Common::ConfigureNvidiaEnvironmentFlags(); |
| 333 | 335 | ||