Implement shared contexts in the EGL context.
This is being implemented here first under EGL since the infrastructure is already in place for this due to the Android code requiring some bits. The rest of the interfaces will come in a little bit. This will be required for threaded shader compiling in the near future.
This commit is contained in:
parent
fdf6fb47e0
commit
aed693eded
|
@ -104,6 +104,7 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
||||||
egl_dpy = OpenDisplay();
|
egl_dpy = OpenDisplay();
|
||||||
m_host_window = (EGLNativeWindowType) window_handle;
|
m_host_window = (EGLNativeWindowType) window_handle;
|
||||||
m_has_handle = !!window_handle;
|
m_has_handle = !!window_handle;
|
||||||
|
m_core = false;
|
||||||
|
|
||||||
if (!egl_dpy)
|
if (!egl_dpy)
|
||||||
{
|
{
|
||||||
|
@ -137,28 +138,28 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
||||||
};
|
};
|
||||||
switch (s_opengl_mode)
|
switch (s_opengl_mode)
|
||||||
{
|
{
|
||||||
case GLInterfaceMode::MODE_OPENGL:
|
case GLInterfaceMode::MODE_OPENGL:
|
||||||
attribs[1] = EGL_OPENGL_BIT;
|
attribs[1] = EGL_OPENGL_BIT;
|
||||||
ctx_attribs[0] = EGL_NONE;
|
ctx_attribs[0] = EGL_NONE;
|
||||||
break;
|
break;
|
||||||
case GLInterfaceMode::MODE_OPENGLES2:
|
case GLInterfaceMode::MODE_OPENGLES2:
|
||||||
attribs[1] = EGL_OPENGL_ES2_BIT;
|
attribs[1] = EGL_OPENGL_ES2_BIT;
|
||||||
ctx_attribs[1] = 2;
|
ctx_attribs[1] = 2;
|
||||||
break;
|
break;
|
||||||
case GLInterfaceMode::MODE_OPENGLES3:
|
case GLInterfaceMode::MODE_OPENGLES3:
|
||||||
attribs[1] = (1 << 6); /* EGL_OPENGL_ES3_BIT_KHR */
|
attribs[1] = (1 << 6); /* EGL_OPENGL_ES3_BIT_KHR */
|
||||||
ctx_attribs[1] = 3;
|
ctx_attribs[1] = 3;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROR_LOG(VIDEO, "Unknown opengl mode set\n");
|
ERROR_LOG(VIDEO, "Unknown opengl mode set\n");
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eglChooseConfig( egl_dpy, attribs, &m_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);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_opengl_mode == GLInterfaceMode::MODE_OPENGL)
|
if (s_opengl_mode == GLInterfaceMode::MODE_OPENGL)
|
||||||
|
@ -170,7 +171,7 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
||||||
if (!egl_ctx)
|
if (!egl_ctx)
|
||||||
{
|
{
|
||||||
INFO_LOG(VIDEO, "Error: eglCreateContext failed\n");
|
INFO_LOG(VIDEO, "Error: eglCreateContext failed\n");
|
||||||
exit(1);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
|
@ -184,12 +185,76 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!CreateWindowSurface())
|
||||||
CreateWindowSurface();
|
{
|
||||||
|
ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed 0x%04x\n", eglGetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterfaceEGL::CreateWindowSurface()
|
std::unique_ptr<cInterfaceBase> cInterfaceEGL::CreateSharedContext()
|
||||||
|
{
|
||||||
|
std::unique_ptr<cInterfaceBase> context = std::make_unique<cInterfaceEGL>();
|
||||||
|
if (!context->Create(this))
|
||||||
|
return nullptr;
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cInterfaceEGL::Create(cInterfaceBase* main_context)
|
||||||
|
{
|
||||||
|
cInterfaceEGL* egl_context = static_cast<cInterfaceEGL*>(main_context);
|
||||||
|
|
||||||
|
egl_dpy = egl_context->egl_dpy;
|
||||||
|
m_core = egl_context->m_core;
|
||||||
|
m_config = egl_context->m_config;
|
||||||
|
m_supports_surfaceless = egl_context->m_supports_surfaceless;
|
||||||
|
m_is_shared = true;
|
||||||
|
m_has_handle = false;
|
||||||
|
|
||||||
|
EGLint ctx_attribs[] = {
|
||||||
|
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (egl_context->GetMode())
|
||||||
|
{
|
||||||
|
case GLInterfaceMode::MODE_OPENGL:
|
||||||
|
ctx_attribs[0] = EGL_NONE;
|
||||||
|
break;
|
||||||
|
case GLInterfaceMode::MODE_OPENGLES2:
|
||||||
|
ctx_attribs[1] = 2;
|
||||||
|
break;
|
||||||
|
case GLInterfaceMode::MODE_OPENGLES3:
|
||||||
|
ctx_attribs[1] = 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
INFO_LOG(VIDEO, "Unknown opengl mode set\n");
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (egl_context->GetMode() == GLInterfaceMode::MODE_OPENGL)
|
||||||
|
eglBindAPI(EGL_OPENGL_API);
|
||||||
|
else
|
||||||
|
eglBindAPI(EGL_OPENGL_ES_API);
|
||||||
|
|
||||||
|
egl_ctx = eglCreateContext(egl_dpy, m_config, egl_context->egl_ctx, ctx_attribs );
|
||||||
|
if (!egl_ctx)
|
||||||
|
{
|
||||||
|
INFO_LOG(VIDEO, "Error: eglCreateContext failed 0x%04x\n", eglGetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CreateWindowSurface())
|
||||||
|
{
|
||||||
|
ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed 0x%04x\n", eglGetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cInterfaceEGL::CreateWindowSurface()
|
||||||
{
|
{
|
||||||
if (m_has_handle)
|
if (m_has_handle)
|
||||||
{
|
{
|
||||||
|
@ -198,7 +263,7 @@ void cInterfaceEGL::CreateWindowSurface()
|
||||||
if (!egl_surf)
|
if (!egl_surf)
|
||||||
{
|
{
|
||||||
INFO_LOG(VIDEO, "Error: eglCreateWindowSurface failed\n");
|
INFO_LOG(VIDEO, "Error: eglCreateWindowSurface failed\n");
|
||||||
exit(1);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!m_supports_surfaceless)
|
else if (!m_supports_surfaceless)
|
||||||
|
@ -211,13 +276,14 @@ void cInterfaceEGL::CreateWindowSurface()
|
||||||
if (!egl_surf)
|
if (!egl_surf)
|
||||||
{
|
{
|
||||||
INFO_LOG(VIDEO, "Error: eglCreatePbufferSurface failed");
|
INFO_LOG(VIDEO, "Error: eglCreatePbufferSurface failed");
|
||||||
exit(2);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
egl_surf = EGL_NO_SURFACE;
|
egl_surf = EGL_NO_SURFACE;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterfaceEGL::DestroyWindowSurface()
|
void cInterfaceEGL::DestroyWindowSurface()
|
||||||
|
@ -255,15 +321,15 @@ bool cInterfaceEGL::ClearCurrent()
|
||||||
void cInterfaceEGL::Shutdown()
|
void cInterfaceEGL::Shutdown()
|
||||||
{
|
{
|
||||||
ShutdownPlatform();
|
ShutdownPlatform();
|
||||||
if (egl_ctx && !eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx))
|
|
||||||
NOTICE_LOG(VIDEO, "Could not release drawing context.");
|
|
||||||
if (egl_ctx)
|
if (egl_ctx)
|
||||||
{
|
{
|
||||||
|
if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx))
|
||||||
|
NOTICE_LOG(VIDEO, "Could not release drawing context.");
|
||||||
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.");
|
||||||
DestroyWindowSurface();
|
DestroyWindowSurface();
|
||||||
if (!eglTerminate(egl_dpy))
|
if (!m_is_shared && !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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ private:
|
||||||
EGLNativeWindowType m_host_window;
|
EGLNativeWindowType m_host_window;
|
||||||
bool m_supports_surfaceless = false;
|
bool m_supports_surfaceless = false;
|
||||||
|
|
||||||
void CreateWindowSurface();
|
bool CreateWindowSurface();
|
||||||
void DestroyWindowSurface();
|
void DestroyWindowSurface();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -26,9 +26,9 @@ protected:
|
||||||
EGLContext egl_ctx;
|
EGLContext egl_ctx;
|
||||||
EGLDisplay egl_dpy;
|
EGLDisplay egl_dpy;
|
||||||
|
|
||||||
virtual EGLDisplay OpenDisplay() = 0;
|
virtual EGLDisplay OpenDisplay() { return EGL_NO_DISPLAY; }
|
||||||
virtual EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) = 0;
|
virtual EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) { return (EGLNativeWindowType)EGL_DEFAULT_DISPLAY; }
|
||||||
virtual void ShutdownPlatform() = 0;
|
virtual void ShutdownPlatform() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Swap() override;
|
void Swap() override;
|
||||||
|
@ -36,9 +36,11 @@ public:
|
||||||
void SetMode(GLInterfaceMode mode) override { s_opengl_mode = mode; }
|
void SetMode(GLInterfaceMode mode) override { s_opengl_mode = mode; }
|
||||||
void* GetFuncAddress(const std::string& name) override;
|
void* GetFuncAddress(const std::string& name) override;
|
||||||
bool Create(void* window_handle, bool core) override;
|
bool Create(void* window_handle, bool core) override;
|
||||||
|
bool Create(cInterfaceBase* main_context) override;
|
||||||
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 UpdateHandle(void* window_handle) override;
|
||||||
void UpdateSurface() override;
|
void UpdateSurface() override;
|
||||||
|
std::unique_ptr<cInterfaceBase> CreateSharedContext() override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,6 +23,8 @@ protected:
|
||||||
// Window dimensions.
|
// Window dimensions.
|
||||||
u32 s_backbuffer_width = 0;
|
u32 s_backbuffer_width = 0;
|
||||||
u32 s_backbuffer_height = 0;
|
u32 s_backbuffer_height = 0;
|
||||||
|
bool m_core = false;
|
||||||
|
bool m_is_shared = false;
|
||||||
|
|
||||||
GLInterfaceMode s_opengl_mode = GLInterfaceMode::MODE_DETECT;
|
GLInterfaceMode s_opengl_mode = GLInterfaceMode::MODE_DETECT;
|
||||||
public:
|
public:
|
||||||
|
@ -32,6 +34,7 @@ public:
|
||||||
virtual GLInterfaceMode GetMode() { return s_opengl_mode; }
|
virtual GLInterfaceMode GetMode() { return s_opengl_mode; }
|
||||||
virtual void* GetFuncAddress(const std::string& name) { return nullptr; }
|
virtual void* GetFuncAddress(const std::string& name) { return nullptr; }
|
||||||
virtual bool Create(void *window_handle, bool core = true) { return true; }
|
virtual bool Create(void *window_handle, bool core = true) { return true; }
|
||||||
|
virtual bool Create(cInterfaceBase* main_context) { return true; }
|
||||||
virtual bool MakeCurrent() { return true; }
|
virtual bool MakeCurrent() { return true; }
|
||||||
virtual bool ClearCurrent() { return true; }
|
virtual bool ClearCurrent() { return true; }
|
||||||
virtual void Shutdown() {}
|
virtual void Shutdown() {}
|
||||||
|
@ -44,6 +47,7 @@ public:
|
||||||
virtual bool PeekMessages() { return false; }
|
virtual bool PeekMessages() { return false; }
|
||||||
virtual void UpdateHandle(void* window_handle) {}
|
virtual void UpdateHandle(void* window_handle) {}
|
||||||
virtual void UpdateSurface() {}
|
virtual void UpdateSurface() {}
|
||||||
|
virtual std::unique_ptr<cInterfaceBase> CreateSharedContext() { return nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::unique_ptr<cInterfaceBase> GLInterface;
|
extern std::unique_ptr<cInterfaceBase> GLInterface;
|
||||||
|
|
Loading…
Reference in New Issue