mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2025-03-21 13:08:38 +01:00
openGL is working!
This commit is contained in:
parent
c22ac3367e
commit
3929d44815
@ -126,8 +126,9 @@ object NativeLibrary {
|
||||
external fun doFrame()
|
||||
|
||||
//Second window
|
||||
external fun enableSecondWindow(secondary_surface: Surface)
|
||||
external fun disableSecondWindow()
|
||||
external fun secondarySurfaceChanged(secondary_surface: Surface)
|
||||
external fun secondarySurfaceDestroyed()
|
||||
external fun disableSecondaryScreen()
|
||||
/**
|
||||
* Unpauses emulation from a paused state.
|
||||
*/
|
||||
|
@ -67,6 +67,9 @@ class EmulationActivity : AppCompatActivity() {
|
||||
private fun updatePresentation() {
|
||||
displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
||||
val display = getCustomerDisplay();
|
||||
if (secondScreenPresentation != null && (IntSetting.SECONDARY_SCREEN_LAYOUT.int == SecondaryScreenLayout.NONE.int || display == null)) {
|
||||
releasePresentation();
|
||||
}
|
||||
if (secondScreenPresentation == null || secondScreenPresentation?.display != display) {
|
||||
secondScreenPresentation?.dismiss()
|
||||
if (display != null && IntSetting.SECONDARY_SCREEN_LAYOUT.int != SecondaryScreenLayout.NONE.int) {
|
||||
@ -76,9 +79,12 @@ class EmulationActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
private fun releasePresentation() {
|
||||
if (secondScreenPresentation != null) {
|
||||
NativeLibrary.disableSecondaryScreen()
|
||||
secondScreenPresentation?.dismiss();
|
||||
secondScreenPresentation = null;
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCustomerDisplay(): Display? {
|
||||
return displayManager?.displays?.firstOrNull { it.isValid && it.displayId != Display.DEFAULT_DISPLAY }
|
||||
|
@ -6,6 +6,8 @@ import android.view.SurfaceHolder
|
||||
import android.view.SurfaceView
|
||||
import org.citra.citra_emu.NativeLibrary
|
||||
|
||||
|
||||
|
||||
class SecondScreenPresentation(
|
||||
context: Context,
|
||||
display: Display,
|
||||
@ -19,7 +21,7 @@ class SecondScreenPresentation(
|
||||
surfaceView = SurfaceView(context)
|
||||
surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
|
||||
override fun surfaceCreated(holder: SurfaceHolder) {
|
||||
NativeLibrary.enableSecondWindow(holder.surface)
|
||||
|
||||
}
|
||||
|
||||
override fun surfaceChanged(
|
||||
@ -28,11 +30,11 @@ class SecondScreenPresentation(
|
||||
width: Int,
|
||||
height: Int
|
||||
) {
|
||||
NativeLibrary.enableSecondWindow(holder.surface)
|
||||
NativeLibrary.secondarySurfaceChanged(holder.surface)
|
||||
}
|
||||
|
||||
override fun surfaceDestroyed(holder: SurfaceHolder) {
|
||||
NativeLibrary.disableSecondWindow();
|
||||
NativeLibrary.secondarySurfaceDestroyed()
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -16,11 +16,15 @@
|
||||
#include <core/hle/service/cfg/cfg.h>
|
||||
#include "audio_core/dsp_interface.h"
|
||||
#include "common/arch.h"
|
||||
|
||||
#if CITRA_ARCH(arm64)
|
||||
|
||||
#include "common/aarch64/cpu_detect.h"
|
||||
|
||||
#elif CITRA_ARCH(x86_64)
|
||||
#include "common/x64/cpu_detect.h"
|
||||
#endif
|
||||
|
||||
#include "common/common_paths.h"
|
||||
#include "common/dynamic_library/dynamic_library.h"
|
||||
#include "common/file_util.h"
|
||||
@ -44,12 +48,18 @@
|
||||
#include "jni/camera/ndk_camera.h"
|
||||
#include "jni/camera/still_image_camera.h"
|
||||
#include "jni/config.h"
|
||||
|
||||
#ifdef ENABLE_OPENGL
|
||||
|
||||
#include "jni/emu_window/emu_window_gl.h"
|
||||
|
||||
#endif
|
||||
#ifdef ENABLE_VULKAN
|
||||
|
||||
#include "jni/emu_window/emu_window_vk.h"
|
||||
|
||||
#endif
|
||||
|
||||
#include "jni/id_cache.h"
|
||||
#include "jni/input_manager.h"
|
||||
#include "jni/ndk_motion.h"
|
||||
@ -59,7 +69,9 @@
|
||||
#include "video_core/renderer_base.h"
|
||||
|
||||
#if defined(ENABLE_VULKAN) && CITRA_ARCH(arm64)
|
||||
|
||||
#include <adrenotools/driver.h>
|
||||
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
@ -156,14 +168,18 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
||||
window = std::make_unique<EmuWindow_Android_OpenGL>(system, s_surf, false);
|
||||
if (secondary_enabled) {
|
||||
EGLContext *c = window->GetEGLContext();
|
||||
second_window = std::make_unique<EmuWindow_Android_OpenGL>(system,s_secondary_surface, true, c);
|
||||
second_window = std::make_unique<EmuWindow_Android_OpenGL>(system,
|
||||
s_secondary_surface,
|
||||
true, c);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef ENABLE_VULKAN
|
||||
case Settings::GraphicsAPI::Vulkan:
|
||||
window = std::make_unique<EmuWindow_Android_Vulkan>(s_surf, vulkan_library, false);
|
||||
if (secondary_enabled) second_window = std::make_unique<EmuWindow_Android_Vulkan>(s_secondary_surface, vulkan_library, true);
|
||||
if (secondary_enabled)
|
||||
second_window = std::make_unique<EmuWindow_Android_Vulkan>(s_secondary_surface,
|
||||
vulkan_library, true);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@ -174,7 +190,9 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
||||
window = std::make_unique<EmuWindow_Android_OpenGL>(system, s_surf, false);
|
||||
if (secondary_enabled) {
|
||||
EGLContext *c = window->GetEGLContext();
|
||||
second_window = std::make_unique<EmuWindow_Android_OpenGL>(system, s_secondary_surface,true, c);
|
||||
second_window = std::make_unique<EmuWindow_Android_OpenGL>(system,
|
||||
s_secondary_surface,
|
||||
true, c);
|
||||
}
|
||||
#elif ENABLE_VULKAN
|
||||
window = std::make_unique<EmuWindow_Android_Vulkan>(s_surf, vulkan_library);
|
||||
@ -217,8 +235,8 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
||||
InputManager::Init();
|
||||
|
||||
window->MakeCurrent();
|
||||
//if (second_window) second_window->MakeCurrent();
|
||||
const Core::System::ResultStatus load_result{system.Load(*window, filepath,second_window.get())};
|
||||
const Core::System::ResultStatus load_result{
|
||||
system.Load(*window, filepath, second_window.get())};
|
||||
if (load_result != Core::System::ResultStatus::Success) {
|
||||
return load_result;
|
||||
}
|
||||
@ -323,15 +341,39 @@ void Java_org_citra_citra_1emu_NativeLibrary_surfaceChanged(JNIEnv* env,
|
||||
LOG_INFO(Frontend, "Surface changed");
|
||||
}
|
||||
|
||||
void Java_org_citra_citra_1emu_NativeLibrary_enableSecondWindow(JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj,jobject surf) {
|
||||
void Java_org_citra_citra_1emu_NativeLibrary_secondarySurfaceChanged(JNIEnv *env,
|
||||
[[maybe_unused]] jobject obj,
|
||||
jobject surf) {
|
||||
auto &system = Core::System::GetInstance();
|
||||
s_secondary_surface = ANativeWindow_fromSurface(env, surf);
|
||||
secondary_enabled = true;
|
||||
bool notify = false;
|
||||
if (second_window) {
|
||||
notify = second_window->OnSurfaceChanged(s_secondary_surface);
|
||||
if (!s_secondary_surface) {
|
||||
// did not create the surface, so disable second screen
|
||||
secondary_enabled = false;
|
||||
if (system.IsPoweredOn()) {
|
||||
system.GPU().Renderer().setSecondaryWindow(nullptr);
|
||||
}
|
||||
auto& system = Core::System::GetInstance();
|
||||
return;
|
||||
}
|
||||
if (second_window) {
|
||||
//second window already created, so update it
|
||||
notify = second_window->OnSurfaceChanged(s_secondary_surface);
|
||||
} else if (system.IsPoweredOn() && window) {
|
||||
// emulation running, window is new
|
||||
// create a new window and set it
|
||||
const auto graphics_api = Settings::values.graphics_api.GetValue();
|
||||
if (graphics_api == Settings::GraphicsAPI::OpenGL) {
|
||||
EGLContext *c = window->GetEGLContext();
|
||||
second_window = std::make_unique<EmuWindow_Android_OpenGL>(system,
|
||||
s_secondary_surface,true, c);
|
||||
}else{
|
||||
second_window = std::make_unique<EmuWindow_Android_Vulkan>(s_secondary_surface,
|
||||
vulkan_library, true);
|
||||
}
|
||||
system.GPU().Renderer().setSecondaryWindow(second_window.get());
|
||||
}
|
||||
|
||||
if (notify && system.IsPoweredOn()) {
|
||||
system.GPU().Renderer().NotifySurfaceChanged(true);
|
||||
}
|
||||
@ -340,22 +382,36 @@ void Java_org_citra_citra_1emu_NativeLibrary_enableSecondWindow(JNIEnv* env,
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Java_org_citra_citra_1emu_NativeLibrary_disableSecondWindow(JNIEnv* env,
|
||||
void Java_org_citra_citra_1emu_NativeLibrary_secondarySurfaceDestroyed(JNIEnv *env,
|
||||
[[maybe_unused]] jobject obj) {
|
||||
|
||||
//auto &system = Core::System::GetInstance();
|
||||
secondary_enabled = false;
|
||||
if (s_secondary_surface != nullptr) {
|
||||
ANativeWindow_release(s_secondary_surface);
|
||||
s_secondary_surface = nullptr;
|
||||
}
|
||||
|
||||
LOG_INFO(Frontend, "Secondary Surface Destroyed");
|
||||
}
|
||||
|
||||
void Java_org_citra_citra_1emu_NativeLibrary_disableSecondaryScreen(JNIEnv *env,
|
||||
[[maybe_unused]] jobject obj) {
|
||||
auto &system = Core::System::GetInstance();
|
||||
secondary_enabled = false;
|
||||
if (s_secondary_surface != nullptr) {
|
||||
ANativeWindow_release(s_secondary_surface);
|
||||
s_secondary_surface = nullptr;
|
||||
}
|
||||
if (system.IsPoweredOn()) {
|
||||
system.GPU().Renderer().setSecondaryWindow(nullptr);
|
||||
}
|
||||
if (second_window) {
|
||||
second_window->OnSurfaceChanged(s_secondary_surface);
|
||||
}
|
||||
second_window.release();
|
||||
second_window = nullptr;
|
||||
}
|
||||
LOG_INFO(Frontend, "Secondary Window Disabled");
|
||||
|
||||
LOG_INFO(Frontend, "Secondary Surface Disabled");
|
||||
}
|
||||
|
||||
void Java_org_citra_citra_1emu_NativeLibrary_surfaceDestroyed([[maybe_unused]] JNIEnv *env,
|
||||
[[maybe_unused]] jobject obj) {
|
||||
if (s_surf != nullptr) {
|
||||
@ -442,7 +498,8 @@ jobjectArray Java_org_citra_citra_1emu_NativeLibrary_getInstalledGamePaths(
|
||||
JNIEnv *env, [[maybe_unused]] jclass clazz) {
|
||||
std::vector<std::string> games;
|
||||
const FileUtil::DirectoryEntryCallable ScanDir =
|
||||
[&games, &ScanDir](u64*, const std::string& directory, const std::string& virtual_name) {
|
||||
[&games, &ScanDir](u64 *, const std::string &directory,
|
||||
const std::string &virtual_name) {
|
||||
std::string path = directory + virtual_name;
|
||||
if (FileUtil::IsDirectory(path)) {
|
||||
path += '/';
|
||||
@ -565,7 +622,8 @@ jboolean Java_org_citra_citra_1emu_NativeLibrary_onGamePadEvent([[maybe_unused]]
|
||||
}
|
||||
|
||||
jboolean Java_org_citra_citra_1emu_NativeLibrary_onGamePadMoveEvent(
|
||||
[[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj, [[maybe_unused]] jstring j_device,
|
||||
[[maybe_unused]] JNIEnv *env, [[maybe_unused]] jobject obj,
|
||||
[[maybe_unused]] jstring j_device,
|
||||
jint axis, jfloat x, jfloat y) {
|
||||
// Clamp joystick movement to supported minimum and maximum
|
||||
// Citra uses an inverted y axis sent by the frontend
|
||||
@ -584,7 +642,8 @@ jboolean Java_org_citra_citra_1emu_NativeLibrary_onGamePadMoveEvent(
|
||||
}
|
||||
|
||||
jboolean Java_org_citra_citra_1emu_NativeLibrary_onGamePadAxisEvent(
|
||||
[[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj, [[maybe_unused]] jstring j_device,
|
||||
[[maybe_unused]] JNIEnv *env, [[maybe_unused]] jobject obj,
|
||||
[[maybe_unused]] jstring j_device,
|
||||
jint axis_id, jfloat axis_val) {
|
||||
return static_cast<jboolean>(
|
||||
InputManager::ButtonHandler()->AnalogButtonEvent(axis_id, axis_val));
|
||||
@ -740,7 +799,8 @@ JNIEXPORT jobject JNICALL Java_org_citra_citra_1emu_utils_CiaInstallWorker_insta
|
||||
Service::AM::InstallStatus res = Service::AM::InstallCIA(
|
||||
path, [env, jobj](std::size_t total_bytes_read, std::size_t file_size) {
|
||||
env->CallVoidMethod(jobj, IDCache::GetCiaInstallHelperSetProgress(),
|
||||
static_cast<jint>(file_size), static_cast<jint>(total_bytes_read));
|
||||
static_cast<jint>(file_size),
|
||||
static_cast<jint>(total_bytes_read));
|
||||
});
|
||||
|
||||
return IDCache::GetJavaCiaInstallStatus(res);
|
||||
@ -767,7 +827,8 @@ jobjectArray Java_org_citra_citra_1emu_NativeLibrary_getSavestateInfo(
|
||||
|
||||
const auto savestates = Core::ListSaveStates(title_id, system.Movie().GetCurrentMovieID());
|
||||
const jobjectArray array =
|
||||
env->NewObjectArray(static_cast<jsize>(savestates.size()), savestate_info_class, nullptr);
|
||||
env->NewObjectArray(static_cast<jsize>(savestates.size()), savestate_info_class,
|
||||
nullptr);
|
||||
for (std::size_t i = 0; i < savestates.size(); ++i) {
|
||||
const jobject object = env->AllocObject(savestate_info_class);
|
||||
env->SetIntField(object, slot_field, static_cast<jint>(savestates[i].slot));
|
||||
|
@ -67,4 +67,13 @@ void RendererBase::RequestScreenshot(void* data, std::function<void(bool)> callb
|
||||
settings.screenshot_requested = true;
|
||||
}
|
||||
|
||||
Frontend::EmuWindow *RendererBase::getSecondaryWindow() const {
|
||||
return secondary_window;
|
||||
}
|
||||
|
||||
void RendererBase::setSecondaryWindow(Frontend::EmuWindow *secondaryWindow) {
|
||||
secondary_window = secondaryWindow;
|
||||
if (secondary_window) secondary_window->PollEvents();
|
||||
}
|
||||
|
||||
} // namespace VideoCore
|
||||
|
@ -111,7 +111,14 @@ protected:
|
||||
Core::System& system;
|
||||
RendererSettings settings;
|
||||
Frontend::EmuWindow& render_window; ///< Reference to the render window handle.
|
||||
Frontend::EmuWindow* secondary_window; ///< Reference to the secondary render window handle.
|
||||
Frontend::EmuWindow* secondary_window;
|
||||
public:
|
||||
Frontend::EmuWindow *getSecondaryWindow() const;
|
||||
|
||||
virtual void setSecondaryWindow(Frontend::EmuWindow *secondaryWindow);
|
||||
|
||||
protected:
|
||||
///< Reference to the secondary render window handle.
|
||||
f32 current_fps = 0.0f; ///< Current framerate, should be set by the renderer
|
||||
s32 current_frame = 0; ///< Current frame, should be set by the renderer
|
||||
};
|
||||
|
@ -87,6 +87,15 @@ RendererOpenGL::RendererOpenGL(Core::System& system, Pica::PicaCore& pica_,
|
||||
}
|
||||
|
||||
RendererOpenGL::~RendererOpenGL() = default;
|
||||
void RendererOpenGL::setSecondaryWindow(Frontend::EmuWindow *secondaryWindow) {
|
||||
if (secondaryWindow) {
|
||||
secondary_window = secondaryWindow;
|
||||
secondary_window->mailbox = std::make_unique<OGLTextureMailbox>(driver.HasDebugTool());
|
||||
}else {
|
||||
secondary_window = nullptr;
|
||||
// should I release something here? The mailbox??
|
||||
}
|
||||
}
|
||||
|
||||
void RendererOpenGL::SwapBuffers() {
|
||||
// Maintain the rasterizer's state as a priority
|
||||
|
@ -54,6 +54,7 @@ public:
|
||||
void PrepareVideoDumping() override;
|
||||
void CleanupVideoDumping() override;
|
||||
void Sync() override;
|
||||
void setSecondaryWindow(Frontend::EmuWindow *secondaryWindow) override;
|
||||
|
||||
private:
|
||||
void InitOpenGLObjects();
|
||||
|
Loading…
x
Reference in New Issue
Block a user