mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 02:41:52 +01:00
Implement graphics pipelines loading screen core logic
This commit is contained in:
parent
8c2b39858d
commit
3bb24a52ab
@ -189,6 +189,7 @@ dependencies {
|
||||
/* Other Java */
|
||||
implementation 'info.debatty:java-string-similarity:2.0.0'
|
||||
implementation 'com.github.KikiManjaro:colorpicker:v1.1.12'
|
||||
implementation 'com.github.android:renderscript-intrinsics-replacement-toolkit:344be3f'
|
||||
}
|
||||
|
||||
kapt {
|
||||
|
@ -63,8 +63,11 @@ namespace skyline {
|
||||
waitForSubmitOrCancelId{environ->GetMethodID(instanceClass, "waitForSubmitOrCancel", "(Lemu/skyline/applet/swkbd/SoftwareKeyboardDialog;)[Ljava/lang/Object;")},
|
||||
closeKeyboardId{environ->GetMethodID(instanceClass, "closeKeyboard", "(Lemu/skyline/applet/swkbd/SoftwareKeyboardDialog;)V")},
|
||||
showValidationResultId{environ->GetMethodID(instanceClass, "showValidationResult", "(Lemu/skyline/applet/swkbd/SoftwareKeyboardDialog;ILjava/lang/String;)I")},
|
||||
getVersionCodeId{environ->GetMethodID(instanceClass, "getVersionCode", "()I")},
|
||||
getIntegerValueId{environ->GetMethodID(environ->FindClass("java/lang/Integer"), "intValue", "()I")} {
|
||||
getIntegerValueId{environ->GetMethodID(environ->FindClass("java/lang/Integer"), "intValue", "()I")},
|
||||
showPipelineLoadingScreenId{environ->GetMethodID(instanceClass, "showPipelineLoadingScreen", "(I)V")},
|
||||
updatePipelineLoadingProgressId{environ->GetMethodID(instanceClass, "updatePipelineLoadingProgress", "(I)V")},
|
||||
hidePipelineLoadingScreenId{environ->GetMethodID(instanceClass, "hidePipelineLoadingScreen", "()V")},
|
||||
getVersionCodeId{environ->GetMethodID(instanceClass, "getVersionCode", "()I")} {
|
||||
env.Initialize(environ);
|
||||
}
|
||||
|
||||
@ -137,14 +140,26 @@ namespace skyline {
|
||||
env->DeleteGlobalRef(dialog);
|
||||
}
|
||||
|
||||
i32 JvmManager::GetVersionCode() {
|
||||
return env->CallIntMethod(instance, getVersionCodeId);
|
||||
}
|
||||
|
||||
JvmManager::KeyboardCloseResult JvmManager::ShowValidationResult(jobject dialog, KeyboardTextCheckResult checkResult, std::u16string message) {
|
||||
auto str{env->NewString(reinterpret_cast<const jchar *>(message.data()), static_cast<int>(message.length()))};
|
||||
auto result{static_cast<KeyboardCloseResult>(env->CallIntMethod(instance, showValidationResultId, dialog, checkResult, str))};
|
||||
env->DeleteLocalRef(str);
|
||||
return result;
|
||||
}
|
||||
|
||||
void JvmManager::ShowPipelineLoadingScreen(u32 totalPipelineCount) {
|
||||
env->CallVoidMethod(instance, showPipelineLoadingScreenId, static_cast<jint>(totalPipelineCount));
|
||||
}
|
||||
|
||||
void JvmManager::UpdatePipelineLoadingProgress(u32 progress) {
|
||||
env->CallVoidMethod(instance, updatePipelineLoadingProgressId, static_cast<jint>(progress));
|
||||
}
|
||||
|
||||
void JvmManager::HidePipelineLoadingScreen() {
|
||||
env->CallVoidMethod(instance, hidePipelineLoadingScreenId);
|
||||
}
|
||||
|
||||
i32 JvmManager::GetVersionCode() {
|
||||
return env->CallIntMethod(instance, getVersionCodeId);
|
||||
}
|
||||
}
|
||||
|
@ -176,6 +176,21 @@ namespace skyline {
|
||||
*/
|
||||
KeyboardCloseResult ShowValidationResult(KeyboardHandle dialog, KeyboardTextCheckResult checkResult, std::u16string message);
|
||||
|
||||
/**
|
||||
* @brief A call to EmulationActivity.showPipelineLoadingScreen in Kotlin
|
||||
*/
|
||||
void ShowPipelineLoadingScreen(u32 totalPipelineCount);
|
||||
|
||||
/**
|
||||
* @brief A call to EmulationActivity.updatePipelineLoadingProgress in Kotlin
|
||||
*/
|
||||
void UpdatePipelineLoadingProgress(u32 progress);
|
||||
|
||||
/**
|
||||
* @brief A call to EmulationActivity.hidePipelineLoadingScreen in Kotlin
|
||||
*/
|
||||
void HidePipelineLoadingScreen();
|
||||
|
||||
/**
|
||||
* @brief A call to EmulationActivity.getVersionCode in Kotlin
|
||||
* @return A version code in Vulkan's format with 14-bit patch + 10-bit major and minor components
|
||||
@ -186,12 +201,17 @@ namespace skyline {
|
||||
jmethodID initializeControllersId;
|
||||
jmethodID vibrateDeviceId;
|
||||
jmethodID clearVibrationDeviceId;
|
||||
|
||||
jmethodID showKeyboardId;
|
||||
jmethodID waitForSubmitOrCancelId;
|
||||
jmethodID closeKeyboardId;
|
||||
jmethodID showValidationResultId;
|
||||
jmethodID getVersionCodeId;
|
||||
|
||||
jmethodID getIntegerValueId;
|
||||
|
||||
jmethodID showPipelineLoadingScreenId;
|
||||
jmethodID updatePipelineLoadingProgressId;
|
||||
jmethodID hidePipelineLoadingScreenId;
|
||||
|
||||
jmethodID getVersionCodeId;
|
||||
};
|
||||
}
|
||||
|
@ -32,12 +32,12 @@ import androidx.core.view.updateMargins
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import emu.skyline.BuildConfig
|
||||
import emu.skyline.applet.swkbd.SoftwareKeyboardConfig
|
||||
import emu.skyline.applet.swkbd.SoftwareKeyboardDialog
|
||||
import emu.skyline.data.AppItem
|
||||
import emu.skyline.data.AppItemTag
|
||||
import emu.skyline.databinding.EmuActivityBinding
|
||||
import emu.skyline.emulation.PipelineLoadingFragment
|
||||
import emu.skyline.input.*
|
||||
import emu.skyline.loader.RomFile
|
||||
import emu.skyline.loader.getRomFormat
|
||||
@ -446,7 +446,7 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration) {
|
||||
override fun onPictureInPictureModeChanged(isInPictureInPictureMode : Boolean, newConfig : Configuration) {
|
||||
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
|
||||
if (isInPictureInPictureMode) {
|
||||
|
||||
@ -463,10 +463,11 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
||||
} else {
|
||||
try {
|
||||
unregisterReceiver(pictureInPictureReceiver)
|
||||
} catch (ignored : Exception) { }
|
||||
} catch (ignored : Exception) {
|
||||
}
|
||||
|
||||
resumeEmulator()
|
||||
|
||||
|
||||
binding.onScreenControllerView.apply {
|
||||
controllerType = inputHandler.getFirstControllerType()
|
||||
isGone = controllerType == ControllerType.None || !appSettings.onScreenControl
|
||||
@ -511,6 +512,44 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
||||
vibrators.clear()
|
||||
}
|
||||
|
||||
private lateinit var pipelineLoadingFragment : PipelineLoadingFragment
|
||||
|
||||
/**
|
||||
* Called by native code to show the pipeline loading progress screen
|
||||
*/
|
||||
@Suppress("unused")
|
||||
fun showPipelineLoadingScreen(totalPipelineCount : Int) {
|
||||
pipelineLoadingFragment = PipelineLoadingFragment.newInstance(item, totalPipelineCount)
|
||||
|
||||
supportFragmentManager
|
||||
.beginTransaction()
|
||||
.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
|
||||
.replace(R.id.emulation_fragment, pipelineLoadingFragment)
|
||||
.commit()
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by native code to update the pipeline loading progress
|
||||
*/
|
||||
@Suppress("unused")
|
||||
fun updatePipelineLoadingProgress(progress : Int) {
|
||||
runOnUiThread {
|
||||
pipelineLoadingFragment.updateProgress(progress)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by native code to hide the pipeline loading progress screen
|
||||
*/
|
||||
@Suppress("unused")
|
||||
fun hidePipelineLoadingScreen() {
|
||||
supportFragmentManager
|
||||
.beginTransaction()
|
||||
.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
|
||||
.remove(pipelineLoadingFragment)
|
||||
.commit()
|
||||
}
|
||||
|
||||
override fun surfaceCreated(holder : SurfaceHolder) {
|
||||
Log.d(Tag, "surfaceCreated Holder: $holder")
|
||||
|
||||
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* Copyright © 2023 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
*/
|
||||
|
||||
package emu.skyline.emulation
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.RenderEffect
|
||||
import android.graphics.Shader
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.android.renderscript.Toolkit
|
||||
import emu.skyline.data.AppItem
|
||||
import emu.skyline.data.AppItemTag
|
||||
import emu.skyline.databinding.PipelineLoadingBinding
|
||||
import emu.skyline.utils.serializable
|
||||
|
||||
private const val TotalPipelineCountTag = "PipelineLoadingFragment::TotalCount"
|
||||
private const val PipelineProgressTag = "PipelineLoadingFragment::Progress"
|
||||
|
||||
class PipelineLoadingFragment : Fragment() {
|
||||
private val item by lazy { requireArguments().serializable<AppItem>(AppItemTag)!! }
|
||||
private val totalPipelineCount by lazy { requireArguments().getInt(TotalPipelineCountTag) }
|
||||
|
||||
private lateinit var binding : PipelineLoadingBinding
|
||||
|
||||
override fun onCreateView(inflater : LayoutInflater, container : ViewGroup?, savedInstanceState : Bundle?) = PipelineLoadingBinding.inflate(inflater).also { binding = it }.root
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onViewCreated(view : View, savedInstanceState : Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.gameTitle.apply {
|
||||
text = item.title
|
||||
isSelected = true
|
||||
}
|
||||
binding.gameVersion.text = item.version
|
||||
binding.gameIcon.setImageBitmap(item.bitmapIcon)
|
||||
|
||||
val progress = savedInstanceState?.getInt(PipelineProgressTag) ?: 0
|
||||
binding.progressBar.max = totalPipelineCount
|
||||
updateProgress(progress)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
binding.backgroundImage.setImageBitmap(item.bitmapIcon)
|
||||
binding.backgroundImage.setRenderEffect(RenderEffect.createBlurEffect(75f, 75f, Shader.TileMode.MIRROR))
|
||||
} else {
|
||||
binding.backgroundImage.setImageBitmap(Toolkit.blur(item.bitmapIcon, 15))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState : Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putInt(PipelineProgressTag, binding.progressBar.progress)
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun updateProgress(progress : Int) {
|
||||
if (!this::binding.isInitialized)
|
||||
return
|
||||
|
||||
binding.progressBar.progress = progress
|
||||
binding.progressLabel.text = "$progress/$totalPipelineCount (${(progress.toFloat() / totalPipelineCount * 100).toInt()}%)"
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(item : AppItem, totalPipelineCount : Int) = PipelineLoadingFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putSerializable(AppItemTag, item)
|
||||
putInt(TotalPipelineCountTag, totalPipelineCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -27,8 +27,8 @@
|
||||
android:layout_gravity="top|left"
|
||||
android:layout_marginLeft="@dimen/onScreenItemHorizontalMargin"
|
||||
android:layout_marginTop="5dp"
|
||||
tools:text="60 FPS\n16.6±0.10ms"
|
||||
android:textColor="@color/colorPerfStatsPrimary" />
|
||||
android:textColor="@color/colorPerfStatsPrimary"
|
||||
tools:text="60 FPS\n16.6±0.10ms" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/on_screen_pause_toggle"
|
||||
@ -53,4 +53,9 @@
|
||||
android:src="@drawable/ic_show"
|
||||
app:tint="#40FFFFFF"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/emulation_fragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</FrameLayout>
|
||||
|
@ -6,7 +6,7 @@
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/game_icon_bg"
|
||||
android:id="@+id/background_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/icon"
|
||||
@ -52,7 +52,7 @@
|
||||
android:layout_marginStart="16dp"
|
||||
android:maxWidth="360dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toTopOf="@+id/shader_info"
|
||||
app:layout_constraintBottom_toTopOf="@+id/pipeline_info"
|
||||
app:layout_constraintEnd_toEndOf="@id/guidelineTextEdge"
|
||||
app:layout_constraintStart_toEndOf="@id/guidelineIconText"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
@ -80,7 +80,7 @@
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/shader_info"
|
||||
android:id="@+id/pipeline_info"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
@ -90,11 +90,11 @@
|
||||
app:layout_constraintTop_toBottomOf="@+id/game_info">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/shaders_compiling"
|
||||
android:id="@+id/pipelines_compiling"
|
||||
style="?attr/textAppearanceBodyMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/compiling_cached_shaders"
|
||||
android:text="@string/compiling_cached_pipelines"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="17sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@ -109,7 +109,7 @@
|
||||
app:trackThickness="10dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/progress"
|
||||
android:id="@+id/progress_label"
|
||||
style="?attr/textAppearanceBodyMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
@ -256,7 +256,7 @@
|
||||
<!-- Software Keyboard -->
|
||||
<string name="input_hint">Input Text</string>
|
||||
<!-- Misc -->
|
||||
<string name="compiling_cached_shaders">Compiling cached shaders...</string>
|
||||
<string name="compiling_cached_pipelines">Compiling cached pipelines...</string>
|
||||
<!--suppress AndroidLintUnusedResources -->
|
||||
<string name="expand_button_title" tools:override="true">Expand</string>
|
||||
<string name="undo">Undo</string>
|
||||
|
Loading…
Reference in New Issue
Block a user