summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java
diff options
context:
space:
mode:
authorMike <7153163+hackbar@users.noreply.github.com>2017-10-25 12:45:03 -0700
committerMike <7153163+hackbar@users.noreply.github.com>2017-11-01 23:39:56 -0700
commit18cb68eb3cfe656a4eb22229a5441c665a54bf3d (patch)
tree8f5ed8376c8e878e4025f1a3457053c48eddb574 /Source/Android/app/src/main/java
parent987d24fe87c5679d055576b8458ee5d2263fc7ab (diff)
Android: Destroy the surface in EmulationFragment onStop.
Emulation needs to be running when the surface is destroyed, but we want to pause in onStop. So call the surfaceDestroyed callback, as this accomplished both.
Diffstat (limited to 'Source/Android/app/src/main/java')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java2
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java237
2 files changed, 137 insertions, 102 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
index 27ec8cd794..8e59d07cca 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
@@ -275,8 +275,6 @@ public final class EmulationActivity extends AppCompatActivity
mImageView.setVisibility(View.GONE);
}
});
-
- mEmulationFragment.startEmulation();
}
else
{
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java
index 393790cf14..263cd597c1 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java
@@ -25,14 +25,9 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
private SharedPreferences mPreferences;
- private Surface mSurface;
-
private InputOverlay mInputOverlay;
- private Thread mEmulationThread;
-
- private String mGamePath;
- private final EmulationState mEmulationState = new EmulationState();
+ private EmulationState mEmulationState;
public static EmulationFragment newInstance(String gamePath)
{
@@ -73,7 +68,8 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
mPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
- mGamePath = getArguments().getString(KEY_GAMEPATH);
+ String gamePath = getArguments().getString(KEY_GAMEPATH);
+ mEmulationState = new EmulationState(gamePath);
}
/**
@@ -116,10 +112,17 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
}
@Override
- public void onStop()
+ public void onResume()
{
- pauseEmulation();
- super.onStop();
+ super.onResume();
+ mEmulationState.run();
+ }
+
+ @Override
+ public void onPause()
+ {
+ mEmulationState.pause();
+ super.onPause();
}
@Override
@@ -158,101 +161,28 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
@Override
public void surfaceCreated(SurfaceHolder holder)
{
- Log.debug("[EmulationFragment] Surface created.");
+ // We purposely don't do anything here.
+ // All work is done in surfaceChanged, which we are guaranteed to get even for surface creation.
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
Log.debug("[EmulationFragment] Surface changed. Resolution: " + width + "x" + height);
-
- if (mEmulationState.isPaused())
- {
- NativeLibrary.UnPauseEmulation();
- }
-
- mSurface = holder.getSurface();
- NativeLibrary.SurfaceChanged(mSurface);
+ mEmulationState.newSurface(holder.getSurface());
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
- Log.debug("[EmulationFragment] Surface destroyed.");
- NativeLibrary.SurfaceDestroyed();
-
- if (mEmulationState.isRunning())
- {
- pauseEmulation();
- }
+ mEmulationState.clearSurface();
}
- public void startEmulation()
+ public void stopEmulation()
{
- synchronized (mEmulationState)
- {
- if (mEmulationState.isStopped())
- {
- Log.debug("[EmulationFragment] Starting emulation thread.");
-
- mEmulationThread = new Thread(mEmulationRunner, "NativeEmulation");
- mEmulationThread.start();
- // The thread will call mEmulationState.run()
- }
- else if (mEmulationState.isPaused())
- {
- Log.debug("[EmulationFragment] Resuming emulation.");
- NativeLibrary.UnPauseEmulation();
- mEmulationState.run();
- }
- else
- {
- Log.debug("[EmulationFragment] Bug, startEmulation called while running.");
- }
- }
+ mEmulationState.stop();
}
- public void stopEmulation() {
- synchronized (mEmulationState)
- {
- if (!mEmulationState.isStopped())
- {
- NativeLibrary.StopEmulation();
- mEmulationState.stop();
- }
- }
- }
-
- private void pauseEmulation()
- {
- synchronized (mEmulationState)
- {
- Log.debug("[EmulationFragment] Pausing emulation.");
-
- NativeLibrary.PauseEmulation();
- mEmulationState.pause();
- }
- }
-
- private Runnable mEmulationRunner = new Runnable()
- {
- @Override
- public void run()
- {
- // Busy-wait for surface to be set
- while (mSurface == null) {}
-
- synchronized (mEmulationState)
- {
- Log.info("[EmulationFragment] Starting emulation: " + mSurface);
-
- mEmulationState.run();
- }
- // Start emulation using the provided Surface.
- NativeLibrary.Run(mGamePath);
- }
- };
-
public void startConfiguringControls()
{
getView().findViewById(R.id.done_control_config).setVisibility(View.VISIBLE);
@@ -277,42 +207,149 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
STOPPED, RUNNING, PAUSED
}
+ private final String mGamePath;
+ private Thread mEmulationThread;
private State state;
+ private Surface mSurface;
+ private boolean mRunWhenSurfaceIsValid;
- EmulationState()
+ EmulationState(String gamePath)
{
+ mGamePath = gamePath;
// Starting state is stopped.
state = State.STOPPED;
}
- public boolean isStopped()
+ // Getters for the current state
+
+ public synchronized boolean isStopped()
{
return state == State.STOPPED;
}
- public boolean isRunning()
+ public synchronized boolean isPaused()
+ {
+ return state == State.PAUSED;
+ }
+
+ public synchronized boolean isRunning()
{
return state == State.RUNNING;
}
- public boolean isPaused()
+ // State changing methods
+
+ public synchronized void stop()
{
- return state == State.PAUSED;
+ if (state != State.STOPPED)
+ {
+ state = State.STOPPED;
+ NativeLibrary.StopEmulation();
+ }
+ else
+ {
+ Log.warning("[EmulationFragment] Stop called while already stopped.");
+ }
}
- public void run()
+ public synchronized void pause()
{
- state = State.RUNNING;
+ if (state != State.PAUSED)
+ {
+ state = State.PAUSED;
+ Log.debug("[EmulationFragment] Pausing emulation.");
+
+ // Release the surface before pausing, since emulation has to be running for that.
+ mSurface = null;
+ NativeLibrary.SurfaceDestroyed();
+ NativeLibrary.PauseEmulation();
+ }
+ else
+ {
+ Log.warning("[EmulationFragment] Pause called while already paused.");
+ }
}
- public void pause()
+ public synchronized void run()
{
- state = State.PAUSED;
+ // If the surface is set, run now. Otherwise, wait for it to get set.
+ if (mSurface != null)
+ {
+ runWithValidSurface();
+ }
+ else
+ {
+ mRunWhenSurfaceIsValid = true;
+ }
}
- public void stop()
+ // Surface callbacks
+ public synchronized void newSurface(Surface surface)
{
- state = State.STOPPED;
+ mSurface = surface;
+ if (mRunWhenSurfaceIsValid)
+ {
+ runWithValidSurface();
+ }
+ }
+
+ public synchronized void clearSurface()
+ {
+ if (mSurface == null)
+ {
+ Log.warning("[EmulationFragment] clearSurface called, but surface already null.");
+ }
+ else
+ {
+ mSurface = null;
+ Log.debug("[EmulationFragment] Surface destroyed.");
+
+ if (state == State.RUNNING)
+ {
+ NativeLibrary.SurfaceDestroyed();
+ state = State.PAUSED;
+ }
+ else if (state == State.PAUSED)
+ {
+ Log.warning("[EmulationFragment] Surface cleared while emulation paused.");
+ }
+ else
+ {
+ Log.warning("[EmulationFragment] Surface cleared while emulation stopped.");
+ }
+ }
+ }
+
+ private void runWithValidSurface()
+ {
+ mRunWhenSurfaceIsValid = false;
+ if (state == State.STOPPED)
+ {
+ Log.debug("[EmulationFragment] Starting emulation thread.");
+
+ mEmulationThread = new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ NativeLibrary.SurfaceChanged(mSurface);
+ NativeLibrary.Run(mGamePath);
+ }},
+ "NativeEmulation");
+ mEmulationThread.start();
+
+ }
+ else if (state == State.PAUSED)
+ {
+ Log.debug("[EmulationFragment] Resuming emulation.");
+ NativeLibrary.UnPauseEmulation();
+ NativeLibrary.SurfaceChanged(mSurface);
+ }
+ else
+ {
+ Log.debug("[EmulationFragment] Bug, run called while already running.");
+ }
+ state = State.RUNNING;
}
}
}