Revert "Presenting in ui thread (#92)"
This reverts commit d1c2e8fb88873bf8642d07ca7e386cc1bac19692.
This commit is contained in:
parent
fe4ff50d5b
commit
1d083cc7db
@ -0,0 +1,26 @@
|
|||||||
|
package org.citra.citra_emu;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.test.InstrumentationRegistry;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumented test, which will execute on an Android device.
|
||||||
|
*
|
||||||
|
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||||
|
*/
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ExampleInstrumentedTest {
|
||||||
|
@Test
|
||||||
|
public void useAppContext() {
|
||||||
|
// Context of the app under test.
|
||||||
|
Context appContext = InstrumentationRegistry.getTargetContext();
|
||||||
|
|
||||||
|
assertEquals("org.citra.citra_emu", appContext.getPackageName());
|
||||||
|
}
|
||||||
|
}
|
@ -172,8 +172,6 @@ public final class NativeLibrary {
|
|||||||
|
|
||||||
public static native void SurfaceDestroyed();
|
public static native void SurfaceDestroyed();
|
||||||
|
|
||||||
public static native void DoFrame();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unpauses emulation from a paused state.
|
* Unpauses emulation from a paused state.
|
||||||
*/
|
*/
|
||||||
|
@ -6,7 +6,6 @@ import android.content.SharedPreferences;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.view.Choreographer;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
@ -31,7 +30,7 @@ import org.citra.citra_emu.utils.DirectoryStateReceiver;
|
|||||||
import org.citra.citra_emu.utils.EmulationMenuSettings;
|
import org.citra.citra_emu.utils.EmulationMenuSettings;
|
||||||
import org.citra.citra_emu.utils.Log;
|
import org.citra.citra_emu.utils.Log;
|
||||||
|
|
||||||
public final class EmulationFragment extends Fragment implements SurfaceHolder.Callback, Choreographer.FrameCallback {
|
public final class EmulationFragment extends Fragment implements SurfaceHolder.Callback {
|
||||||
private static final String KEY_GAMEPATH = "gamepath";
|
private static final String KEY_GAMEPATH = "gamepath";
|
||||||
|
|
||||||
private static final Handler perfStatsUpdateHandler = new Handler();
|
private static final Handler perfStatsUpdateHandler = new Handler();
|
||||||
@ -115,7 +114,6 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Choreographer.getInstance().postFrameCallback(this);
|
|
||||||
if (DirectoryInitialization.areCitraDirectoriesReady()) {
|
if (DirectoryInitialization.areCitraDirectoriesReady()) {
|
||||||
mEmulationState.run(activity.isActivityRecreated());
|
mEmulationState.run(activity.isActivityRecreated());
|
||||||
} else {
|
} else {
|
||||||
@ -130,11 +128,8 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
|
|||||||
directoryStateReceiver = null;
|
directoryStateReceiver = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mEmulationState.isRunning()) {
|
if (mEmulationState.isRunning())
|
||||||
mEmulationState.pause();
|
mEmulationState.pause();
|
||||||
}
|
|
||||||
|
|
||||||
Choreographer.getInstance().removeFrameCallback(this);
|
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,12 +227,6 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
|
|||||||
mEmulationState.clearSurface();
|
mEmulationState.clearSurface();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doFrame(long frameTimeNanos) {
|
|
||||||
Choreographer.getInstance().postFrameCallback(this);
|
|
||||||
NativeLibrary.DoFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopEmulation() {
|
public void stopEmulation() {
|
||||||
mEmulationState.stop();
|
mEmulationState.stop();
|
||||||
}
|
}
|
||||||
@ -353,9 +342,9 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
|
|||||||
private void runWithValidSurface() {
|
private void runWithValidSurface() {
|
||||||
mRunWhenSurfaceIsValid = false;
|
mRunWhenSurfaceIsValid = false;
|
||||||
if (state == State.STOPPED) {
|
if (state == State.STOPPED) {
|
||||||
NativeLibrary.SurfaceChanged(mSurface);
|
|
||||||
Thread mEmulationThread = new Thread(() ->
|
Thread mEmulationThread = new Thread(() ->
|
||||||
{
|
{
|
||||||
|
NativeLibrary.SurfaceChanged(mSurface);
|
||||||
Log.debug("[EmulationFragment] Starting emulation thread.");
|
Log.debug("[EmulationFragment] Starting emulation thread.");
|
||||||
NativeLibrary.Run(mGamePath);
|
NativeLibrary.Run(mGamePath);
|
||||||
}, "NativeEmulation");
|
}, "NativeEmulation");
|
||||||
|
@ -79,7 +79,6 @@ static void UpdateLandscapeScreenLayout() {
|
|||||||
|
|
||||||
void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) {
|
void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) {
|
||||||
render_window = surface;
|
render_window = surface;
|
||||||
StopPresenting();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmuWindow_Android::OnTouchEvent(int x, int y, bool pressed) {
|
bool EmuWindow_Android::OnTouchEvent(int x, int y, bool pressed) {
|
||||||
@ -220,6 +219,7 @@ void EmuWindow_Android::DestroyContext() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EmuWindow_Android::~EmuWindow_Android() {
|
EmuWindow_Android::~EmuWindow_Android() {
|
||||||
|
StopPresenting();
|
||||||
DestroyWindowSurface();
|
DestroyWindowSurface();
|
||||||
DestroyContext();
|
DestroyContext();
|
||||||
}
|
}
|
||||||
@ -228,26 +228,34 @@ std::unique_ptr<Frontend::GraphicsContext> EmuWindow_Android::CreateSharedContex
|
|||||||
return std::make_unique<SharedContext_Android>(egl_display, egl_config, egl_context);
|
return std::make_unique<SharedContext_Android>(egl_display, egl_config, egl_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuWindow_Android::StopPresenting() {
|
void EmuWindow_Android::StartPresenting() {
|
||||||
if (presenting_state == PresentingState::Running) {
|
ASSERT(!presentation_thread);
|
||||||
eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
is_presenting = true;
|
||||||
}
|
presentation_thread =
|
||||||
presenting_state = PresentingState::Stopped;
|
std::make_unique<std::thread>([emu_window{this}] { emu_window->Present(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuWindow_Android::TryPresenting() {
|
void EmuWindow_Android::StopPresenting() {
|
||||||
if (presenting_state != PresentingState::Running) {
|
is_presenting = false;
|
||||||
if (presenting_state == PresentingState::Initial) {
|
if (presentation_thread) {
|
||||||
|
presentation_thread->join();
|
||||||
|
presentation_thread.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EmuWindow_Android::IsPresenting() const {
|
||||||
|
return is_presenting;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuWindow_Android::Present() {
|
||||||
eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
|
eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
presenting_state = PresentingState::Running;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eglSwapInterval(egl_display, Settings::values.use_vsync_new ? 1 : 0);
|
eglSwapInterval(egl_display, Settings::values.use_vsync_new ? 1 : 0);
|
||||||
|
while (IsPresenting()) {
|
||||||
VideoCore::g_renderer->TryPresent(100);
|
VideoCore::g_renderer->TryPresent(100);
|
||||||
eglSwapBuffers(egl_display, egl_surface);
|
eglSwapBuffers(egl_display, egl_surface);
|
||||||
|
}
|
||||||
|
eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuWindow_Android::PollEvents() {
|
void EmuWindow_Android::PollEvents() {
|
||||||
@ -258,10 +266,14 @@ void EmuWindow_Android::PollEvents() {
|
|||||||
host_window = render_window;
|
host_window = render_window;
|
||||||
render_window = nullptr;
|
render_window = nullptr;
|
||||||
|
|
||||||
|
if (IsPresenting()) {
|
||||||
|
StopPresenting();
|
||||||
|
}
|
||||||
|
|
||||||
DestroyWindowSurface();
|
DestroyWindowSurface();
|
||||||
CreateWindowSurface();
|
CreateWindowSurface();
|
||||||
OnFramebufferSizeChanged();
|
OnFramebufferSizeChanged();
|
||||||
presenting_state = PresentingState::Initial;
|
StartPresenting();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuWindow_Android::MakeCurrent() {
|
void EmuWindow_Android::MakeCurrent() {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
@ -50,8 +51,9 @@ public:
|
|||||||
void MakeCurrent() override;
|
void MakeCurrent() override;
|
||||||
void DoneCurrent() override;
|
void DoneCurrent() override;
|
||||||
|
|
||||||
void TryPresenting();
|
void StartPresenting();
|
||||||
void StopPresenting();
|
void StopPresenting();
|
||||||
|
bool IsPresenting() const;
|
||||||
|
|
||||||
std::unique_ptr<GraphicsContext> CreateSharedContext() const override;
|
std::unique_ptr<GraphicsContext> CreateSharedContext() const override;
|
||||||
|
|
||||||
@ -74,10 +76,7 @@ private:
|
|||||||
|
|
||||||
std::unique_ptr<Frontend::GraphicsContext> core_context;
|
std::unique_ptr<Frontend::GraphicsContext> core_context;
|
||||||
|
|
||||||
enum class PresentingState {
|
std::unique_ptr<std::thread> presentation_thread;
|
||||||
Initial,
|
|
||||||
Running,
|
bool is_presenting{};
|
||||||
Stopped,
|
|
||||||
};
|
|
||||||
PresentingState presenting_state{};
|
|
||||||
};
|
};
|
||||||
|
@ -102,6 +102,7 @@ static void TryShutdown() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window->StopPresenting();
|
||||||
window->DoneCurrent();
|
window->DoneCurrent();
|
||||||
Core::System::GetInstance().Shutdown();
|
Core::System::GetInstance().Shutdown();
|
||||||
window.reset();
|
window.reset();
|
||||||
@ -166,6 +167,8 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
|||||||
is_running = true;
|
is_running = true;
|
||||||
pause_emulation = false;
|
pause_emulation = false;
|
||||||
|
|
||||||
|
window->StartPresenting();
|
||||||
|
|
||||||
SCOPE_EXIT({ TryShutdown(); });
|
SCOPE_EXIT({ TryShutdown(); });
|
||||||
|
|
||||||
// Audio stretching on Android is only useful with lower framerates, disable it when fullspeed
|
// Audio stretching on Android is only useful with lower framerates, disable it when fullspeed
|
||||||
@ -193,7 +196,6 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
|||||||
|
|
||||||
std::unique_lock<std::mutex> pause_lock(paused_mutex);
|
std::unique_lock<std::mutex> pause_lock(paused_mutex);
|
||||||
running_cv.wait(pause_lock, [] { return !pause_emulation || !is_running; });
|
running_cv.wait(pause_lock, [] { return !pause_emulation || !is_running; });
|
||||||
window->PollEvents();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,13 +225,6 @@ void Java_org_citra_citra_1emu_NativeLibrary_SurfaceDestroyed(JNIEnv* env,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Java_org_citra_citra_1emu_NativeLibrary_DoFrame(JNIEnv* env, [[maybe_unused]] jclass clazz) {
|
|
||||||
if (!is_running || pause_emulation) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
window->TryPresenting();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_citra_citra_1emu_NativeLibrary_NotifyOrientationChange(JNIEnv* env,
|
void Java_org_citra_citra_1emu_NativeLibrary_NotifyOrientationChange(JNIEnv* env,
|
||||||
[[maybe_unused]] jclass clazz,
|
[[maybe_unused]] jclass clazz,
|
||||||
jint layout_option,
|
jint layout_option,
|
||||||
@ -307,7 +302,6 @@ void Java_org_citra_citra_1emu_NativeLibrary_StopEmulation(JNIEnv* env,
|
|||||||
[[maybe_unused]] jclass clazz) {
|
[[maybe_unused]] jclass clazz) {
|
||||||
is_running = false;
|
is_running = false;
|
||||||
pause_emulation = false;
|
pause_emulation = false;
|
||||||
window->StopPresenting();
|
|
||||||
running_cv.notify_all();
|
running_cv.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package org.citra.citra_emu;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
*
|
||||||
|
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||||
|
*/
|
||||||
|
public class ExampleUnitTest {
|
||||||
|
@Test
|
||||||
|
public void addition_isCorrect() {
|
||||||
|
assertEquals(4, 2 + 2);
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.6.3'
|
classpath 'com.android.tools.build:gradle:3.6.1'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
Loading…
x
Reference in New Issue
Block a user