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();
|
||||
m_host_window = (EGLNativeWindowType) window_handle;
|
||||
m_has_handle = !!window_handle;
|
||||
m_core = false;
|
||||
|
||||
if (!egl_dpy)
|
||||
{
|
||||
|
@ -137,28 +138,28 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
|||
};
|
||||
switch (s_opengl_mode)
|
||||
{
|
||||
case GLInterfaceMode::MODE_OPENGL:
|
||||
attribs[1] = EGL_OPENGL_BIT;
|
||||
ctx_attribs[0] = EGL_NONE;
|
||||
break;
|
||||
case GLInterfaceMode::MODE_OPENGLES2:
|
||||
attribs[1] = EGL_OPENGL_ES2_BIT;
|
||||
ctx_attribs[1] = 2;
|
||||
break;
|
||||
case GLInterfaceMode::MODE_OPENGLES3:
|
||||
attribs[1] = (1 << 6); /* EGL_OPENGL_ES3_BIT_KHR */
|
||||
ctx_attribs[1] = 3;
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(VIDEO, "Unknown opengl mode set\n");
|
||||
return false;
|
||||
break;
|
||||
case GLInterfaceMode::MODE_OPENGL:
|
||||
attribs[1] = EGL_OPENGL_BIT;
|
||||
ctx_attribs[0] = EGL_NONE;
|
||||
break;
|
||||
case GLInterfaceMode::MODE_OPENGLES2:
|
||||
attribs[1] = EGL_OPENGL_ES2_BIT;
|
||||
ctx_attribs[1] = 2;
|
||||
break;
|
||||
case GLInterfaceMode::MODE_OPENGLES3:
|
||||
attribs[1] = (1 << 6); /* EGL_OPENGL_ES3_BIT_KHR */
|
||||
ctx_attribs[1] = 3;
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(VIDEO, "Unknown opengl mode set\n");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!eglChooseConfig( egl_dpy, attribs, &m_config, 1, &num_configs))
|
||||
{
|
||||
INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config\n");
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s_opengl_mode == GLInterfaceMode::MODE_OPENGL)
|
||||
|
@ -170,7 +171,7 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
|||
if (!egl_ctx)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Error: eglCreateContext failed\n");
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string tmp;
|
||||
|
@ -184,12 +185,76 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
CreateWindowSurface();
|
||||
if (!CreateWindowSurface())
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed 0x%04x\n", eglGetError());
|
||||
return false;
|
||||
}
|
||||
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)
|
||||
{
|
||||
|
@ -198,7 +263,7 @@ void cInterfaceEGL::CreateWindowSurface()
|
|||
if (!egl_surf)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Error: eglCreateWindowSurface failed\n");
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!m_supports_surfaceless)
|
||||
|
@ -211,13 +276,14 @@ void cInterfaceEGL::CreateWindowSurface()
|
|||
if (!egl_surf)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Error: eglCreatePbufferSurface failed");
|
||||
exit(2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
egl_surf = EGL_NO_SURFACE;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void cInterfaceEGL::DestroyWindowSurface()
|
||||
|
@ -255,15 +321,15 @@ bool cInterfaceEGL::ClearCurrent()
|
|||
void cInterfaceEGL::Shutdown()
|
||||
{
|
||||
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 (!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);
|
||||
if (!eglDestroyContext(egl_dpy, egl_ctx))
|
||||
NOTICE_LOG(VIDEO, "Could not destroy drawing context.");
|
||||
DestroyWindowSurface();
|
||||
if (!eglTerminate(egl_dpy))
|
||||
if (!m_is_shared && !eglTerminate(egl_dpy))
|
||||
NOTICE_LOG(VIDEO, "Could not destroy display connection.");
|
||||
egl_ctx = nullptr;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ private:
|
|||
EGLNativeWindowType m_host_window;
|
||||
bool m_supports_surfaceless = false;
|
||||
|
||||
void CreateWindowSurface();
|
||||
bool CreateWindowSurface();
|
||||
void DestroyWindowSurface();
|
||||
|
||||
protected:
|
||||
|
@ -26,9 +26,9 @@ protected:
|
|||
EGLContext egl_ctx;
|
||||
EGLDisplay egl_dpy;
|
||||
|
||||
virtual EGLDisplay OpenDisplay() = 0;
|
||||
virtual EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) = 0;
|
||||
virtual void ShutdownPlatform() = 0;
|
||||
virtual EGLDisplay OpenDisplay() { return EGL_NO_DISPLAY; }
|
||||
virtual EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) { return (EGLNativeWindowType)EGL_DEFAULT_DISPLAY; }
|
||||
virtual void ShutdownPlatform() {}
|
||||
|
||||
public:
|
||||
void Swap() override;
|
||||
|
@ -36,9 +36,11 @@ public:
|
|||
void SetMode(GLInterfaceMode mode) override { s_opengl_mode = mode; }
|
||||
void* GetFuncAddress(const std::string& name) override;
|
||||
bool Create(void* window_handle, bool core) override;
|
||||
bool Create(cInterfaceBase* main_context) override;
|
||||
bool MakeCurrent() override;
|
||||
bool ClearCurrent() override;
|
||||
void Shutdown() override;
|
||||
void UpdateHandle(void* window_handle) override;
|
||||
void UpdateSurface() override;
|
||||
std::unique_ptr<cInterfaceBase> CreateSharedContext() override;
|
||||
};
|
||||
|
|
|
@ -23,6 +23,8 @@ protected:
|
|||
// Window dimensions.
|
||||
u32 s_backbuffer_width = 0;
|
||||
u32 s_backbuffer_height = 0;
|
||||
bool m_core = false;
|
||||
bool m_is_shared = false;
|
||||
|
||||
GLInterfaceMode s_opengl_mode = GLInterfaceMode::MODE_DETECT;
|
||||
public:
|
||||
|
@ -32,6 +34,7 @@ public:
|
|||
virtual GLInterfaceMode GetMode() { return s_opengl_mode; }
|
||||
virtual void* GetFuncAddress(const std::string& name) { return nullptr; }
|
||||
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 ClearCurrent() { return true; }
|
||||
virtual void Shutdown() {}
|
||||
|
@ -44,6 +47,7 @@ public:
|
|||
virtual bool PeekMessages() { return false; }
|
||||
virtual void UpdateHandle(void* window_handle) {}
|
||||
virtual void UpdateSurface() {}
|
||||
virtual std::unique_ptr<cInterfaceBase> CreateSharedContext() { return nullptr; }
|
||||
};
|
||||
|
||||
extern std::unique_ptr<cInterfaceBase> GLInterface;
|
||||
|
|
Loading…
Reference in New Issue