add GamePerformanceSdk
This commit is contained in:
parent
0976656c34
commit
d221880aaa
8
Assets/GamePerformanceSdk/Plugins.meta
Normal file
8
Assets/GamePerformanceSdk/Plugins.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac3a1b0385b933a4ba752182b9aff19e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/GamePerformanceSdk/Plugins/Android.meta
Normal file
8
Assets/GamePerformanceSdk/Plugins/Android.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2a5b10838cdc174f87fbc9ad15c12fe
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<application android:appCategory="game">
|
||||
<activity android:name="com.x.gamesdk.GameActivity"
|
||||
android:theme="@style/UnityThemeSelector">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8255a3bd1c76aaf469a428a56ef5debf
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
28
Assets/GamePerformanceSdk/Plugins/Android/GameActivity.java
Normal file
28
Assets/GamePerformanceSdk/Plugins/Android/GameActivity.java
Normal file
@ -0,0 +1,28 @@
|
||||
package com.x.gamesdk;
|
||||
|
||||
import com.unity3d.player.UnityPlayerActivity;
|
||||
import android.os.Bundle;
|
||||
import android.os.Build;
|
||||
|
||||
public class GameActivity extends UnityPlayerActivity {
|
||||
|
||||
private String appendCommandLineArgument(String cmdLine, String arg) {
|
||||
if (arg == null || arg.isEmpty())
|
||||
return cmdLine;
|
||||
else if (cmdLine == null || cmdLine.isEmpty())
|
||||
return arg;
|
||||
else
|
||||
return cmdLine + " " + arg;
|
||||
}
|
||||
|
||||
@Override protected String updateUnityCommandLineArguments(String cmdLine)
|
||||
{
|
||||
return cmdLine; // 让 Unity 根据 PlayerSettings 选择图形 API
|
||||
}
|
||||
|
||||
@Override protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
new GameSdk(getBaseContext());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a38f11cc1647a8f44b8dbc93244d95f5
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
177
Assets/GamePerformanceSdk/Plugins/Android/GamePerformanceSdk.cs
Normal file
177
Assets/GamePerformanceSdk/Plugins/Android/GamePerformanceSdk.cs
Normal file
@ -0,0 +1,177 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
[DefaultExecutionOrder(-9000)]
|
||||
public unsafe class GamePerformanceSdk : MonoBehaviour
|
||||
{
|
||||
private static AndroidJavaObject s_GameSDK = null;
|
||||
private static IntPtr s_GameSDKRawObjectID;
|
||||
private static IntPtr s_SupportPerformanceHintMethodId;
|
||||
private static IntPtr s_SetPerfHitTargetNanosfHintMethodId;
|
||||
private static IntPtr s_ReportPerfHintMethodId;
|
||||
private static IntPtr s_SupportGameStateMethodId;
|
||||
private static IntPtr s_SetGameStateMethodId;
|
||||
|
||||
private static jvalue[] s_NoArgs = new jvalue[0];
|
||||
|
||||
private jvalue[] ReportPerfHintMethodArgs = new jvalue[1];
|
||||
private jvalue[] SetGameStateMethodArgs = new jvalue[2];
|
||||
|
||||
private bool supportGameStateApi = true;
|
||||
private bool supportPerformanceHintApi = true;
|
||||
|
||||
private static IntPtr GetJavaMethodID(IntPtr classId, string name, string sig)
|
||||
{
|
||||
AndroidJNI.ExceptionClear();
|
||||
var mid = AndroidJNI.GetMethodID(classId, name, sig);
|
||||
|
||||
IntPtr ex = AndroidJNI.ExceptionOccurred();
|
||||
if (ex != (IntPtr)0)
|
||||
{
|
||||
AndroidJNI.ExceptionDescribe();
|
||||
AndroidJNI.ExceptionClear();
|
||||
return (IntPtr)0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
|
||||
public enum GameState
|
||||
{
|
||||
MODE_UNKNOWN = 0,
|
||||
/**
|
||||
* No mode means that the game is not in active play, for example the user is using the game
|
||||
* menu.
|
||||
*/
|
||||
MODE_NONE = 1,
|
||||
|
||||
/**
|
||||
* Indicates if the game is in active, but interruptible, game play.
|
||||
*/
|
||||
MODE_GAMEPLAY_INTERRUPTIBLE = 2,
|
||||
|
||||
/**
|
||||
* Indicates if the game is in active user play mode, which is real time and cannot be
|
||||
* interrupted.
|
||||
*/
|
||||
MODE_GAMEPLAY_UNINTERRUPTIBLE = 3,
|
||||
|
||||
/**
|
||||
* Indicates that the current content shown is not gameplay related. For example it can be an
|
||||
* ad, a web page, a text, or a video.
|
||||
*/
|
||||
MODE_CONTENT = 4
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Application.targetFrameRate = 120;
|
||||
|
||||
s_GameSDK = new AndroidJavaObject("com.x.gamesdk.GameSdk").CallStatic<AndroidJavaObject>("getInstance");
|
||||
if (s_GameSDK != null)
|
||||
{
|
||||
Debug.Log("Init GamePerformanceSdk start.");
|
||||
s_GameSDKRawObjectID = s_GameSDK.GetRawObject();
|
||||
|
||||
var classID = s_GameSDK.GetRawClass();
|
||||
s_SupportPerformanceHintMethodId = GetJavaMethodID(classID, "SupportPerformanceHint", "()Z");
|
||||
if (s_SupportPerformanceHintMethodId != IntPtr.Zero)
|
||||
{
|
||||
supportPerformanceHintApi = AndroidJNI.CallBooleanMethod(s_GameSDKRawObjectID, s_SupportPerformanceHintMethodId, s_NoArgs);
|
||||
}
|
||||
|
||||
s_ReportPerfHintMethodId = GetJavaMethodID(classID, "ReportPerfHint", "(J)V");
|
||||
if (s_ReportPerfHintMethodId != IntPtr.Zero)
|
||||
{
|
||||
Debug.Log("found ReportPerfHint.");
|
||||
}
|
||||
|
||||
s_SetPerfHitTargetNanosfHintMethodId = GetJavaMethodID(classID, "SetPerfHitTargetNanos", "(J)V");
|
||||
if (s_SetPerfHitTargetNanosfHintMethodId != IntPtr.Zero)
|
||||
{
|
||||
Debug.Log("found SetPerfHitTargetNanos.");
|
||||
SetTargetFps(120);
|
||||
}
|
||||
|
||||
s_SupportGameStateMethodId = GetJavaMethodID(classID, "SupportGameState", "()Z");
|
||||
if (s_SupportGameStateMethodId != IntPtr.Zero)
|
||||
{
|
||||
supportGameStateApi = AndroidJNI.CallBooleanMethod(s_GameSDKRawObjectID, s_SupportGameStateMethodId, s_NoArgs);
|
||||
}
|
||||
|
||||
s_SetGameStateMethodId = GetJavaMethodID(classID, "SetGameState", "(ZI)V");
|
||||
if (s_SetGameStateMethodId != IntPtr.Zero)
|
||||
{
|
||||
Debug.Log("found SetGameState.");
|
||||
}
|
||||
|
||||
Debug.Log($"Init GamePerformanceSdk done. supportGameStateApi:{supportGameStateApi} supportPerformanceHintApi:{supportPerformanceHintApi}");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
RenderPipelineManager.endFrameRendering += OnEndFrameRendering;
|
||||
}
|
||||
|
||||
float time = 0;
|
||||
System.Diagnostics.Stopwatch stopwatch = new();
|
||||
|
||||
// XXX: insert to early update
|
||||
private void Update()
|
||||
{
|
||||
time = Time.realtimeSinceStartup;
|
||||
stopwatch.Restart();
|
||||
}
|
||||
|
||||
private void OnEndFrameRendering(ScriptableRenderContext context, Camera[] arg2)
|
||||
{
|
||||
var dt = Time.realtimeSinceStartup - time;
|
||||
stopwatch.Stop();
|
||||
if (s_ReportPerfHintMethodId != IntPtr.Zero)
|
||||
{
|
||||
ReportPerfHintMethodArgs[0] = new jvalue() { j = stopwatch.ElapsedMilliseconds * 1000 * 1000 };
|
||||
AndroidJNI.CallVoidMethod(s_GameSDKRawObjectID, s_ReportPerfHintMethodId, ReportPerfHintMethodArgs);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
RenderPipelineManager.endFrameRendering -= OnEndFrameRendering;
|
||||
}
|
||||
|
||||
public void SetTargetFps(int fps)
|
||||
{
|
||||
ReportPerfHintMethodArgs[0] = new jvalue() { j = (long)(1000f / fps * 1000 * 1000) };
|
||||
AndroidJNI.CallVoidMethod(s_GameSDKRawObjectID, s_SetPerfHitTargetNanosfHintMethodId, ReportPerfHintMethodArgs);
|
||||
}
|
||||
|
||||
public void SetGameState(bool isLoading, GameState gameState)
|
||||
{
|
||||
SetGameStateMethodArgs[0] = new jvalue() { z = isLoading };
|
||||
SetGameStateMethodArgs[1] = new jvalue() { i = (int)gameState };
|
||||
|
||||
AndroidJNI.CallVoidMethod(s_GameSDKRawObjectID, s_SetGameStateMethodId, SetGameStateMethodArgs);
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
if (GUI.Button(new Rect(100, 100, 150, 50), "SetLoding"))
|
||||
{
|
||||
SetGameState(true, GameState.MODE_GAMEPLAY_INTERRUPTIBLE);
|
||||
}
|
||||
|
||||
if (GUI.Button(new Rect(100, 180, 150, 50), "SetUninterruptible"))
|
||||
{
|
||||
SetGameState(false, GameState.MODE_GAMEPLAY_UNINTERRUPTIBLE);
|
||||
}
|
||||
|
||||
if (GUI.Button(new Rect(100, 260, 150, 50), "SetUnknown"))
|
||||
{
|
||||
SetGameState(false, GameState.MODE_UNKNOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb094df10d730994d95a79fd42061d77
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
60
Assets/GamePerformanceSdk/Plugins/Android/GameSdk.java
Normal file
60
Assets/GamePerformanceSdk/Plugins/Android/GameSdk.java
Normal file
@ -0,0 +1,60 @@
|
||||
package com.x.gamesdk;
|
||||
|
||||
import android.app.*;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.PerformanceHintManager;
|
||||
import android.os.Process;
|
||||
import android.util.Log;
|
||||
|
||||
public class GameSdk {
|
||||
private static final String LOG_TAG = "GamePerformacneSDK";
|
||||
private static GameSdk instane;
|
||||
|
||||
private final Context context;
|
||||
private PerformanceHintManager.Session performanceHintSession;
|
||||
|
||||
public static GameSdk getInstance() {
|
||||
return instane;
|
||||
}
|
||||
|
||||
public GameSdk(Context context) {
|
||||
instane = this;
|
||||
this.context = context;
|
||||
Log.d(LOG_TAG, "new Game Performance sdk.SupportGameState:" + SupportGameState() + "|Build.VERSION.SDK_INT:" + Build.VERSION.SDK_INT);
|
||||
|
||||
try {
|
||||
PerformanceHintManager performanceHintManager = context.getSystemService(PerformanceHintManager.class);
|
||||
performanceHintSession = performanceHintManager.createHintSession(new int[]{Process.myTid()}, 16666666);
|
||||
Log.d(LOG_TAG, "create performance Hint Session." + performanceHintSession + "|tid:" + Process.myTid());
|
||||
} catch (Exception e) {
|
||||
Log.d(LOG_TAG, "create performance Hint err:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean SupportGameState() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU;
|
||||
}
|
||||
|
||||
public boolean SupportPerformanceHint() {
|
||||
return performanceHintSession != null;
|
||||
}
|
||||
|
||||
public void SetGameState(boolean isLoading, int gameState) {
|
||||
try {
|
||||
GameManager gameManager = context.getSystemService(GameManager.class);
|
||||
if (SupportGameState()) {
|
||||
gameManager.setGameState(new GameState(isLoading, gameState));
|
||||
Log.d(LOG_TAG, "set game state.");
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPerfHitTargetNanos( long targetNs) {
|
||||
performanceHintSession.updateTargetWorkDuration(targetNs);
|
||||
}
|
||||
public void ReportPerfHint(long durantionNs) {
|
||||
performanceHintSession.reportActualWorkDuration(durantionNs);
|
||||
}
|
||||
}
|
||||
32
Assets/GamePerformanceSdk/Plugins/Android/GameSdk.java.meta
Normal file
32
Assets/GamePerformanceSdk/Plugins/Android/GameSdk.java.meta
Normal file
@ -0,0 +1,32 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b395be1482ba044c827eb603f632eca
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
x
Reference in New Issue
Block a user