mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-05 00:40:00 +00:00
Merge pull request #3494 from Sonicadvance1/android_rotation
[Android] Add support for rotation and minimizing the application
This commit is contained in:
commit
78bb37b29f
@ -333,10 +333,12 @@ public final class NativeLibrary
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Begins emulation.
|
* Begins emulation.
|
||||||
*
|
|
||||||
* @param surf The surface to render to.
|
|
||||||
*/
|
*/
|
||||||
public static native void Run(Surface surf);
|
public static native void Run();
|
||||||
|
|
||||||
|
// Surface Handling
|
||||||
|
public static native void SurfaceChanged(Surface surf);
|
||||||
|
public static native void SurfaceDestroyed();
|
||||||
|
|
||||||
/** Unpauses emulation from a paused state. */
|
/** Unpauses emulation from a paused state. */
|
||||||
public static native void UnPauseEmulation();
|
public static native void UnPauseEmulation();
|
||||||
|
@ -177,13 +177,16 @@ public final class EmulationActivity extends AppCompatActivity
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Instantiate an EmulationFragment.
|
if (savedInstanceState == null)
|
||||||
EmulationFragment emulationFragment = EmulationFragment.newInstance(path);
|
{
|
||||||
|
// Instantiate an EmulationFragment.
|
||||||
|
EmulationFragment emulationFragment = EmulationFragment.newInstance(path);
|
||||||
|
|
||||||
// Add fragment to the activity - this triggers all its lifecycle callbacks.
|
// Add fragment to the activity - this triggers all its lifecycle callbacks.
|
||||||
getFragmentManager().beginTransaction()
|
getFragmentManager().beginTransaction()
|
||||||
.add(R.id.frame_emulation_fragment, emulationFragment, EmulationFragment.FRAGMENT_TAG)
|
.add(R.id.frame_emulation_fragment, emulationFragment, EmulationFragment.FRAGMENT_TAG)
|
||||||
.commit();
|
.commit();
|
||||||
|
}
|
||||||
|
|
||||||
if (mDeviceHasTouchScreen)
|
if (mDeviceHasTouchScreen)
|
||||||
{
|
{
|
||||||
|
@ -115,7 +115,6 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
|
|||||||
public void onStop()
|
public void onStop()
|
||||||
{
|
{
|
||||||
super.onStop();
|
super.onStop();
|
||||||
pauseEmulation();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -160,12 +159,14 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
|
|||||||
{
|
{
|
||||||
Log.d("DolphinEmu", "Surface changed. Resolution: " + width + "x" + height);
|
Log.d("DolphinEmu", "Surface changed. Resolution: " + width + "x" + height);
|
||||||
mSurface = holder.getSurface();
|
mSurface = holder.getSurface();
|
||||||
|
NativeLibrary.SurfaceChanged(mSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void surfaceDestroyed(SurfaceHolder holder)
|
public void surfaceDestroyed(SurfaceHolder holder)
|
||||||
{
|
{
|
||||||
Log.d("DolphinEmu", "Surface destroyed.");
|
Log.d("DolphinEmu", "Surface destroyed.");
|
||||||
|
NativeLibrary.SurfaceDestroyed();
|
||||||
|
|
||||||
if (mEmulationRunning)
|
if (mEmulationRunning)
|
||||||
{
|
{
|
||||||
@ -216,20 +217,14 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
|
|||||||
mEmulationRunning = true;
|
mEmulationRunning = true;
|
||||||
mEmulationStarted = true;
|
mEmulationStarted = true;
|
||||||
|
|
||||||
// Loop until onSurfaceCreated succeeds
|
|
||||||
while (mSurface == null)
|
while (mSurface == null)
|
||||||
{
|
|
||||||
if (!mEmulationRunning)
|
if (!mEmulationRunning)
|
||||||
{
|
|
||||||
// So that if the user quits before this gets a surface, we don't loop infinitely.
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.i("DolphinEmu", "Starting emulation: " + mSurface);
|
Log.i("DolphinEmu", "Starting emulation: " + mSurface);
|
||||||
|
|
||||||
// Start emulation using the provided Surface.
|
// Start emulation using the provided Surface.
|
||||||
NativeLibrary.Run(mSurface);
|
NativeLibrary.Run();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "Common/CPUDetect.h"
|
#include "Common/CPUDetect.h"
|
||||||
#include "Common/Event.h"
|
#include "Common/Event.h"
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
|
#include "Common/GL/GLInterfaceBase.h"
|
||||||
#include "Common/Logging/LogManager.h"
|
#include "Common/Logging/LogManager.h"
|
||||||
|
|
||||||
#include "Core/BootManager.h"
|
#include "Core/BootManager.h"
|
||||||
@ -380,16 +381,17 @@ JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetUserDi
|
|||||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetProfiling(JNIEnv *env, jobject obj, jboolean enable);
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetProfiling(JNIEnv *env, jobject obj, jboolean enable);
|
||||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_WriteProfileResults(JNIEnv *env, jobject obj);
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_WriteProfileResults(JNIEnv *env, jobject obj);
|
||||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_CacheClassesAndMethods(JNIEnv *env, jobject obj);
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_CacheClassesAndMethods(JNIEnv *env, jobject obj);
|
||||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *env, jobject obj, jobject _surf);
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *env, jobject obj);
|
||||||
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceChanged(JNIEnv *env, jobject obj, jobject _surf);
|
||||||
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestroyed(JNIEnv *env, jobject obj);
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_UnPauseEmulation(JNIEnv *env, jobject obj)
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_UnPauseEmulation(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
PowerPC::Start();
|
Core::SetState(Core::CORE_RUN);
|
||||||
}
|
}
|
||||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_PauseEmulation(JNIEnv *env, jobject obj)
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_PauseEmulation(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
PowerPC::Pause();
|
Core::SetState(Core::CORE_PAUSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulation(JNIEnv *env, jobject obj)
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulation(JNIEnv *env, jobject obj)
|
||||||
@ -596,18 +598,45 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_CacheClasses
|
|||||||
g_jni_method_end = env->GetStaticMethodID(g_jni_class, "endEmulationActivity", "()V");
|
g_jni_method_end = env->GetStaticMethodID(g_jni_class, "endEmulationActivity", "()V");
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *env, jobject obj, jobject _surf)
|
// Surface Handling
|
||||||
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceChanged(JNIEnv *env, jobject obj, jobject _surf)
|
||||||
|
{
|
||||||
|
surf = ANativeWindow_fromSurface(env, _surf);
|
||||||
|
if (surf == nullptr)
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, DOLPHIN_TAG, "Error: Surface is null.");
|
||||||
|
|
||||||
|
// If GLInterface isn't a thing yet then we don't need to let it know that the surface has changed
|
||||||
|
if (GLInterface)
|
||||||
|
{
|
||||||
|
GLInterface->UpdateHandle(surf);
|
||||||
|
Renderer::s_ChangedSurface.Reset();
|
||||||
|
Renderer::s_SurfaceNeedsChanged.Set();
|
||||||
|
Renderer::s_ChangedSurface.Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestroyed(JNIEnv *env, jobject obj)
|
||||||
|
{
|
||||||
|
if (surf)
|
||||||
|
{
|
||||||
|
ANativeWindow_release(surf);
|
||||||
|
surf = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If GLInterface isn't a thing yet then we don't need to let it know that the surface has changed
|
||||||
|
if (GLInterface)
|
||||||
|
{
|
||||||
|
GLInterface->UpdateHandle(nullptr);
|
||||||
|
Renderer::s_ChangedSurface.Reset();
|
||||||
|
Renderer::s_SurfaceNeedsChanged.Set();
|
||||||
|
Renderer::s_ChangedSurface.Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
__android_log_print(ANDROID_LOG_INFO, DOLPHIN_TAG, "Running : %s", g_filename.c_str());
|
__android_log_print(ANDROID_LOG_INFO, DOLPHIN_TAG, "Running : %s", g_filename.c_str());
|
||||||
|
|
||||||
surf = ANativeWindow_fromSurface(env, _surf);
|
|
||||||
|
|
||||||
if (surf == nullptr)
|
|
||||||
{
|
|
||||||
__android_log_print(ANDROID_LOG_ERROR, DOLPHIN_TAG, "Error: Surface is null.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Install our callbacks
|
// Install our callbacks
|
||||||
OSD::AddCallback(OSD::CallbackType::Initialization, ButtonManager::Init);
|
OSD::AddCallback(OSD::CallbackType::Initialization, ButtonManager::Init);
|
||||||
OSD::AddCallback(OSD::CallbackType::Shutdown, ButtonManager::Shutdown);
|
OSD::AddCallback(OSD::CallbackType::Shutdown, ButtonManager::Shutdown);
|
||||||
@ -627,7 +656,12 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *
|
|||||||
|
|
||||||
Core::Shutdown();
|
Core::Shutdown();
|
||||||
UICommon::Shutdown();
|
UICommon::Shutdown();
|
||||||
ANativeWindow_release(surf);
|
|
||||||
|
if (surf)
|
||||||
|
{
|
||||||
|
ANativeWindow_release(surf);
|
||||||
|
surf = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Execute the Java method.
|
// Execute the Java method.
|
||||||
env->CallStaticVoidMethod(g_jni_class, g_jni_method_end);
|
env->CallStaticVoidMethod(g_jni_class, g_jni_method_end);
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
// Show the current FPS
|
// Show the current FPS
|
||||||
void cInterfaceEGL::Swap()
|
void cInterfaceEGL::Swap()
|
||||||
{
|
{
|
||||||
eglSwapBuffers(egl_dpy, egl_surf);
|
if (egl_surf != EGL_NO_SURFACE)
|
||||||
|
eglSwapBuffers(egl_dpy, egl_surf);
|
||||||
}
|
}
|
||||||
void cInterfaceEGL::SwapInterval(int Interval)
|
void cInterfaceEGL::SwapInterval(int Interval)
|
||||||
{
|
{
|
||||||
@ -98,10 +99,11 @@ void cInterfaceEGL::DetectMode()
|
|||||||
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
|
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
|
||||||
bool cInterfaceEGL::Create(void *window_handle, bool core)
|
bool cInterfaceEGL::Create(void *window_handle, bool core)
|
||||||
{
|
{
|
||||||
const char *s;
|
|
||||||
EGLint egl_major, egl_minor;
|
EGLint egl_major, egl_minor;
|
||||||
|
|
||||||
egl_dpy = OpenDisplay();
|
egl_dpy = OpenDisplay();
|
||||||
|
m_host_window = (EGLNativeWindowType) window_handle;
|
||||||
|
m_has_handle = !!window_handle;
|
||||||
|
|
||||||
if (!egl_dpy)
|
if (!egl_dpy)
|
||||||
{
|
{
|
||||||
@ -116,7 +118,6 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Detection code */
|
/* Detection code */
|
||||||
EGLConfig config;
|
|
||||||
EGLint num_configs;
|
EGLint num_configs;
|
||||||
|
|
||||||
DetectMode();
|
DetectMode();
|
||||||
@ -154,7 +155,7 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs))
|
if (!eglChooseConfig( egl_dpy, attribs, &m_config, 1, &num_configs))
|
||||||
{
|
{
|
||||||
INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config\n");
|
INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -165,43 +166,86 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
|||||||
else
|
else
|
||||||
eglBindAPI(EGL_OPENGL_ES_API);
|
eglBindAPI(EGL_OPENGL_ES_API);
|
||||||
|
|
||||||
EGLNativeWindowType host_window = (EGLNativeWindowType) window_handle;
|
egl_ctx = eglCreateContext(egl_dpy, m_config, EGL_NO_CONTEXT, ctx_attribs );
|
||||||
EGLNativeWindowType native_window = InitializePlatform(host_window, config);
|
|
||||||
|
|
||||||
s = eglQueryString(egl_dpy, EGL_VERSION);
|
|
||||||
INFO_LOG(VIDEO, "EGL_VERSION = %s\n", s);
|
|
||||||
|
|
||||||
s = eglQueryString(egl_dpy, EGL_VENDOR);
|
|
||||||
INFO_LOG(VIDEO, "EGL_VENDOR = %s\n", s);
|
|
||||||
|
|
||||||
s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
|
|
||||||
INFO_LOG(VIDEO, "EGL_EXTENSIONS = %s\n", s);
|
|
||||||
|
|
||||||
s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
|
|
||||||
INFO_LOG(VIDEO, "EGL_CLIENT_APIS = %s\n", s);
|
|
||||||
|
|
||||||
egl_ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs );
|
|
||||||
if (!egl_ctx)
|
if (!egl_ctx)
|
||||||
{
|
{
|
||||||
INFO_LOG(VIDEO, "Error: eglCreateContext failed\n");
|
INFO_LOG(VIDEO, "Error: eglCreateContext failed\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
egl_surf = eglCreateWindowSurface(egl_dpy, config, native_window, nullptr);
|
std::string tmp;
|
||||||
if (!egl_surf)
|
std::istringstream buffer(eglQueryString(egl_dpy, EGL_EXTENSIONS));
|
||||||
|
while (buffer >> tmp)
|
||||||
{
|
{
|
||||||
INFO_LOG(VIDEO, "Error: eglCreateWindowSurface failed\n");
|
if (tmp == "EGL_KHR_surfaceless_context")
|
||||||
exit(1);
|
{
|
||||||
|
m_supports_surfaceless = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CreateWindowSurface();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cInterfaceEGL::CreateWindowSurface()
|
||||||
|
{
|
||||||
|
if (m_has_handle)
|
||||||
|
{
|
||||||
|
EGLNativeWindowType native_window = InitializePlatform(m_host_window, m_config);
|
||||||
|
egl_surf = eglCreateWindowSurface(egl_dpy, m_config, native_window, nullptr);
|
||||||
|
if (!egl_surf)
|
||||||
|
{
|
||||||
|
INFO_LOG(VIDEO, "Error: eglCreateWindowSurface failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!m_supports_surfaceless)
|
||||||
|
{
|
||||||
|
EGLint attrib_list[] =
|
||||||
|
{
|
||||||
|
EGL_NONE,
|
||||||
|
};
|
||||||
|
egl_surf = eglCreatePbufferSurface(egl_dpy, m_config, attrib_list);
|
||||||
|
if (!egl_surf)
|
||||||
|
{
|
||||||
|
INFO_LOG(VIDEO, "Error: eglCreatePbufferSurface failed");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
egl_surf = EGL_NO_SURFACE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cInterfaceEGL::DestroyWindowSurface()
|
||||||
|
{
|
||||||
|
if (egl_surf != EGL_NO_SURFACE && !eglDestroySurface(egl_dpy, egl_surf))
|
||||||
|
NOTICE_LOG(VIDEO, "Could not destroy window surface.");
|
||||||
|
egl_surf = EGL_NO_SURFACE;
|
||||||
|
}
|
||||||
|
|
||||||
bool cInterfaceEGL::MakeCurrent()
|
bool cInterfaceEGL::MakeCurrent()
|
||||||
{
|
{
|
||||||
return eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx);
|
return eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cInterfaceEGL::UpdateHandle(void* window_handle)
|
||||||
|
{
|
||||||
|
m_host_window = (EGLNativeWindowType)window_handle;
|
||||||
|
m_has_handle = !!window_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cInterfaceEGL::UpdateSurface()
|
||||||
|
{
|
||||||
|
ClearCurrent();
|
||||||
|
DestroyWindowSurface();
|
||||||
|
CreateWindowSurface();
|
||||||
|
MakeCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
bool cInterfaceEGL::ClearCurrent()
|
bool cInterfaceEGL::ClearCurrent()
|
||||||
{
|
{
|
||||||
return eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
return eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
@ -218,8 +262,7 @@ void cInterfaceEGL::Shutdown()
|
|||||||
eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
if (!eglDestroyContext(egl_dpy, egl_ctx))
|
if (!eglDestroyContext(egl_dpy, egl_ctx))
|
||||||
NOTICE_LOG(VIDEO, "Could not destroy drawing context.");
|
NOTICE_LOG(VIDEO, "Could not destroy drawing context.");
|
||||||
if (!eglDestroySurface(egl_dpy, egl_surf))
|
DestroyWindowSurface();
|
||||||
NOTICE_LOG(VIDEO, "Could not destroy window surface.");
|
|
||||||
if (!eglTerminate(egl_dpy))
|
if (!eglTerminate(egl_dpy))
|
||||||
NOTICE_LOG(VIDEO, "Could not destroy display connection.");
|
NOTICE_LOG(VIDEO, "Could not destroy display connection.");
|
||||||
egl_ctx = nullptr;
|
egl_ctx = nullptr;
|
||||||
|
@ -11,6 +11,15 @@
|
|||||||
|
|
||||||
class cInterfaceEGL : public cInterfaceBase
|
class cInterfaceEGL : public cInterfaceBase
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
EGLConfig m_config;
|
||||||
|
bool m_has_handle;
|
||||||
|
EGLNativeWindowType m_host_window;
|
||||||
|
bool m_supports_surfaceless = false;
|
||||||
|
|
||||||
|
void CreateWindowSurface();
|
||||||
|
void DestroyWindowSurface();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void DetectMode();
|
void DetectMode();
|
||||||
EGLSurface egl_surf;
|
EGLSurface egl_surf;
|
||||||
@ -20,6 +29,7 @@ protected:
|
|||||||
virtual EGLDisplay OpenDisplay() = 0;
|
virtual EGLDisplay OpenDisplay() = 0;
|
||||||
virtual EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) = 0;
|
virtual EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) = 0;
|
||||||
virtual void ShutdownPlatform() = 0;
|
virtual void ShutdownPlatform() = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Swap() override;
|
void Swap() override;
|
||||||
void SwapInterval(int interval) override;
|
void SwapInterval(int interval) override;
|
||||||
@ -29,4 +39,6 @@ public:
|
|||||||
bool MakeCurrent() override;
|
bool MakeCurrent() override;
|
||||||
bool ClearCurrent() override;
|
bool ClearCurrent() override;
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
|
void UpdateHandle(void* window_handle) override;
|
||||||
|
void UpdateSurface() override;
|
||||||
};
|
};
|
||||||
|
@ -42,6 +42,8 @@ public:
|
|||||||
virtual void SetBackBufferDimensions(u32 W, u32 H) {s_backbuffer_width = W; s_backbuffer_height = H; }
|
virtual void SetBackBufferDimensions(u32 W, u32 H) {s_backbuffer_width = W; s_backbuffer_height = H; }
|
||||||
virtual void Update() { }
|
virtual void Update() { }
|
||||||
virtual bool PeekMessages() { return false; }
|
virtual bool PeekMessages() { return false; }
|
||||||
|
virtual void UpdateHandle(void* window_handle) {}
|
||||||
|
virtual void UpdateSurface() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::unique_ptr<cInterfaceBase> GLInterface;
|
extern std::unique_ptr<cInterfaceBase> GLInterface;
|
||||||
|
@ -1467,6 +1467,13 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
|
|||||||
OSD::DoCallbacks(OSD::CallbackType::OnFrame);
|
OSD::DoCallbacks(OSD::CallbackType::OnFrame);
|
||||||
OSD::DrawMessages();
|
OSD::DrawMessages();
|
||||||
|
|
||||||
|
if (s_SurfaceNeedsChanged.IsSet())
|
||||||
|
{
|
||||||
|
GLInterface->UpdateSurface();
|
||||||
|
s_SurfaceNeedsChanged.Clear();
|
||||||
|
s_ChangedSurface.Set();
|
||||||
|
}
|
||||||
|
|
||||||
// Copy the rendered frame to the real window
|
// Copy the rendered frame to the real window
|
||||||
GLInterface->Swap();
|
GLInterface->Swap();
|
||||||
|
|
||||||
|
@ -58,6 +58,10 @@ Common::Event Renderer::s_screenshotCompleted;
|
|||||||
|
|
||||||
volatile bool Renderer::s_bScreenshot;
|
volatile bool Renderer::s_bScreenshot;
|
||||||
|
|
||||||
|
// Final surface changing
|
||||||
|
Common::Flag Renderer::s_SurfaceNeedsChanged;
|
||||||
|
Common::Event Renderer::s_ChangedSurface;
|
||||||
|
|
||||||
// The framebuffer size
|
// The framebuffer size
|
||||||
int Renderer::s_target_width;
|
int Renderer::s_target_width;
|
||||||
int Renderer::s_target_height;
|
int Renderer::s_target_height;
|
||||||
|
@ -138,6 +138,10 @@ public:
|
|||||||
|
|
||||||
static Common::Event s_screenshotCompleted;
|
static Common::Event s_screenshotCompleted;
|
||||||
|
|
||||||
|
// Final surface changing
|
||||||
|
static Common::Flag s_SurfaceNeedsChanged;
|
||||||
|
static Common::Event s_ChangedSurface;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static void CalculateTargetScale(int x, int y, int* scaledX, int* scaledY);
|
static void CalculateTargetScale(int x, int y, int* scaledX, int* scaledY);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user