Add support to EGL to on the fly destroy the resulting surface
This commit is contained in:
parent
d17bcbb489
commit
6448e5e5ee
|
@ -11,7 +11,8 @@
|
|||
// Show the current FPS
|
||||
void cInterfaceEGL::Swap()
|
||||
{
|
||||
eglSwapBuffers(egl_dpy, egl_surf);
|
||||
if (egl_surf != EGL_NO_SURFACE)
|
||||
eglSwapBuffers(egl_dpy, egl_surf);
|
||||
}
|
||||
void cInterfaceEGL::SwapInterval(int Interval)
|
||||
{
|
||||
|
@ -98,10 +99,11 @@ void cInterfaceEGL::DetectMode()
|
|||
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
|
||||
bool cInterfaceEGL::Create(void *window_handle, bool core)
|
||||
{
|
||||
const char *s;
|
||||
EGLint egl_major, egl_minor;
|
||||
|
||||
egl_dpy = OpenDisplay();
|
||||
m_host_window = (EGLNativeWindowType) window_handle;
|
||||
m_has_handle = !!window_handle;
|
||||
|
||||
if (!egl_dpy)
|
||||
{
|
||||
|
@ -116,7 +118,6 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
|||
}
|
||||
|
||||
/* Detection code */
|
||||
EGLConfig config;
|
||||
EGLint num_configs;
|
||||
|
||||
DetectMode();
|
||||
|
@ -154,7 +155,7 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
|||
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");
|
||||
exit(1);
|
||||
|
@ -165,43 +166,86 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
|||
else
|
||||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
|
||||
EGLNativeWindowType host_window = (EGLNativeWindowType) window_handle;
|
||||
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 );
|
||||
egl_ctx = eglCreateContext(egl_dpy, m_config, EGL_NO_CONTEXT, ctx_attribs );
|
||||
if (!egl_ctx)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Error: eglCreateContext failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
egl_surf = eglCreateWindowSurface(egl_dpy, config, native_window, nullptr);
|
||||
if (!egl_surf)
|
||||
std::string tmp;
|
||||
std::istringstream buffer(eglQueryString(egl_dpy, EGL_EXTENSIONS));
|
||||
while (buffer >> tmp)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Error: eglCreateWindowSurface failed\n");
|
||||
exit(1);
|
||||
if (tmp == "EGL_KHR_surfaceless_context")
|
||||
{
|
||||
m_supports_surfaceless = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CreateWindowSurface();
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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);
|
||||
if (!eglDestroyContext(egl_dpy, egl_ctx))
|
||||
NOTICE_LOG(VIDEO, "Could not destroy drawing context.");
|
||||
if (!eglDestroySurface(egl_dpy, egl_surf))
|
||||
NOTICE_LOG(VIDEO, "Could not destroy window surface.");
|
||||
DestroyWindowSurface();
|
||||
if (!eglTerminate(egl_dpy))
|
||||
NOTICE_LOG(VIDEO, "Could not destroy display connection.");
|
||||
egl_ctx = nullptr;
|
||||
|
|
|
@ -11,6 +11,15 @@
|
|||
|
||||
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:
|
||||
void DetectMode();
|
||||
EGLSurface egl_surf;
|
||||
|
@ -20,6 +29,7 @@ protected:
|
|||
virtual EGLDisplay OpenDisplay() = 0;
|
||||
virtual EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) = 0;
|
||||
virtual void ShutdownPlatform() = 0;
|
||||
|
||||
public:
|
||||
void Swap() override;
|
||||
void SwapInterval(int interval) override;
|
||||
|
@ -29,4 +39,6 @@ public:
|
|||
bool MakeCurrent() override;
|
||||
bool ClearCurrent() 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 Update() { }
|
||||
virtual bool PeekMessages() { return false; }
|
||||
virtual void UpdateHandle(void* window_handle) {}
|
||||
virtual void UpdateSurface() {}
|
||||
};
|
||||
|
||||
extern std::unique_ptr<cInterfaceBase> GLInterface;
|
||||
|
|
Loading…
Reference in New Issue