diff options
| author | Stenzek <stenzek@gmail.com> | 2018-10-03 23:02:45 +1000 |
|---|---|---|
| committer | Stenzek <stenzek@gmail.com> | 2018-10-20 21:11:34 +1000 |
| commit | 134d967be2dd4ba9531abb8ba8494c3ac423ca72 (patch) | |
| tree | 3486a0d8a8f5c1a141bccc1e9cc56306cde327b4 /Source/Core/Common/GL/GLInterface/EGL.cpp | |
| parent | 74b82bab3b6e4e8a1799bbcbdc5244f20f4d2826 (diff) | |
Refactoring and cleanup of GLInterface (now GLContext)
Diffstat (limited to 'Source/Core/Common/GL/GLInterface/EGL.cpp')
| -rw-r--r-- | Source/Core/Common/GL/GLInterface/EGL.cpp | 213 |
1 files changed, 102 insertions, 111 deletions
diff --git a/Source/Core/Common/GL/GLInterface/EGL.cpp b/Source/Core/Common/GL/GLInterface/EGL.cpp index e71b365928..46073fe074 100644 --- a/Source/Core/Common/GL/GLInterface/EGL.cpp +++ b/Source/Core/Common/GL/GLInterface/EGL.cpp @@ -28,35 +28,35 @@ #define EGL_OPENGL_ES3_BIT_KHR 0x00000040 #endif /* EGL_KHR_create_context */ -// Show the current FPS -void cInterfaceEGL::Swap() +GLContextEGL::~GLContextEGL() = default; + +bool GLContextEGL::IsHeadless() const { - if (egl_surf != EGL_NO_SURFACE) - eglSwapBuffers(egl_dpy, egl_surf); + return m_host_window == nullptr; } -void cInterfaceEGL::SwapInterval(int Interval) + +void GLContextEGL::Swap() { - eglSwapInterval(egl_dpy, Interval); + if (m_egl_surface != EGL_NO_SURFACE) + eglSwapBuffers(m_egl_display, m_egl_surface); +} +void GLContextEGL::SwapInterval(int interval) +{ + eglSwapInterval(m_egl_display, interval); } -void* cInterfaceEGL::GetFuncAddress(const std::string& name) +void* GLContextEGL::GetFuncAddress(const std::string& name) { return (void*)eglGetProcAddress(name.c_str()); } -void cInterfaceEGL::DetectMode() +void GLContextEGL::DetectMode(bool has_handle) { - if (s_opengl_mode != GLInterfaceMode::MODE_DETECT) - return; bool preferGLES = Config::Get(Config::GFX_PREFER_GLES); EGLint num_configs; - bool supportsGL = false, supportsGLES2 = false, supportsGLES3 = false; - std::array<int, 3> renderable_types{{ - EGL_OPENGL_BIT, - (1 << 6), /* EGL_OPENGL_ES3_BIT_KHR */ - EGL_OPENGL_ES2_BIT, - }}; + bool supportsGL = false, supportsGLES3 = false; + std::array<int, 3> renderable_types{{EGL_OPENGL_BIT, EGL_OPENGL_ES3_BIT_KHR}}; for (auto renderable_type : renderable_types) { @@ -71,11 +71,11 @@ void cInterfaceEGL::DetectMode() EGL_RENDERABLE_TYPE, renderable_type, EGL_SURFACE_TYPE, - m_has_handle ? EGL_WINDOW_BIT : 0, + has_handle ? EGL_WINDOW_BIT : 0, EGL_NONE}; // Get how many configs there are - if (!eglChooseConfig(egl_dpy, attribs, nullptr, 0, &num_configs)) + if (!eglChooseConfig(m_egl_display, attribs, nullptr, 0, &num_configs)) { INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config"); continue; @@ -84,7 +84,7 @@ void cInterfaceEGL::DetectMode() EGLConfig* config = new EGLConfig[num_configs]; // Get all the configurations - if (!eglChooseConfig(egl_dpy, attribs, config, num_configs, &num_configs)) + if (!eglChooseConfig(m_egl_display, attribs, config, num_configs, &num_configs)) { INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config"); delete[] config; @@ -95,15 +95,13 @@ void cInterfaceEGL::DetectMode() { EGLint attribVal; bool ret; - ret = eglGetConfigAttrib(egl_dpy, config[i], EGL_RENDERABLE_TYPE, &attribVal); + ret = eglGetConfigAttrib(m_egl_display, config[i], EGL_RENDERABLE_TYPE, &attribVal); if (ret) { if (attribVal & EGL_OPENGL_BIT) supportsGL = true; - if (attribVal & (1 << 6)) /* EGL_OPENGL_ES3_BIT_KHR */ + if (attribVal & EGL_OPENGL_ES3_BIT_KHR) supportsGLES3 = true; - if (attribVal & EGL_OPENGL_ES2_BIT) - supportsGLES2 = true; } } delete[] config; @@ -112,63 +110,66 @@ void cInterfaceEGL::DetectMode() if (preferGLES) { if (supportsGLES3) - s_opengl_mode = GLInterfaceMode::MODE_OPENGLES3; - else if (supportsGLES2) - s_opengl_mode = GLInterfaceMode::MODE_OPENGLES2; + m_opengl_mode = Mode::OpenGLES; else if (supportsGL) - s_opengl_mode = GLInterfaceMode::MODE_OPENGL; + m_opengl_mode = Mode::OpenGL; } else { if (supportsGL) - s_opengl_mode = GLInterfaceMode::MODE_OPENGL; + m_opengl_mode = Mode::OpenGL; else if (supportsGLES3) - s_opengl_mode = GLInterfaceMode::MODE_OPENGLES3; - else if (supportsGLES2) - s_opengl_mode = GLInterfaceMode::MODE_OPENGLES2; + m_opengl_mode = Mode::OpenGLES; } - if (s_opengl_mode == GLInterfaceMode::MODE_OPENGL) + if (m_opengl_mode == Mode::OpenGL) { INFO_LOG(VIDEO, "Using OpenGL"); } - else if (s_opengl_mode == GLInterfaceMode::MODE_OPENGLES3) + else if (m_opengl_mode == Mode::OpenGLES) { - INFO_LOG(VIDEO, "Using OpenGL|ES 3"); + INFO_LOG(VIDEO, "Using OpenGL|ES"); } - else if (s_opengl_mode == GLInterfaceMode::MODE_OPENGLES2) - { - INFO_LOG(VIDEO, "Using OpenGL|ES 2"); - } - else if (s_opengl_mode == GLInterfaceMode::MODE_DETECT) + else if (m_opengl_mode == Mode::Detect) { // Errored before we found a mode ERROR_LOG(VIDEO, "Error: Failed to detect OpenGL flavour, falling back to OpenGL"); // This will fail to create a context, as it'll try to use the same attribs we just failed to // find a matching config with - s_opengl_mode = GLInterfaceMode::MODE_OPENGL; + m_opengl_mode = Mode::OpenGL; } } +EGLDisplay GLContextEGL::OpenEGLDisplay() +{ + return eglGetDisplay(EGL_DEFAULT_DISPLAY); +} + +EGLNativeWindowType GLContextEGL::GetEGLNativeWindow(EGLConfig config) +{ + return reinterpret_cast<EGLNativeWindowType>(EGL_DEFAULT_DISPLAY); +} + // Create rendering window. // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() -bool cInterfaceEGL::Create(void* window_handle, bool stereo, bool core) +bool GLContextEGL::Initialize(void* window_handle, bool stereo, bool core) { + const bool has_handle = !!window_handle; + EGLint egl_major, egl_minor; bool supports_core_profile = false; - egl_dpy = OpenDisplay(); - m_host_window = (EGLNativeWindowType)window_handle; - m_has_handle = !!window_handle; - m_core = core; + m_egl_display = OpenEGLDisplay(); + m_host_window = window_handle; + m_is_core_context = core; - if (!egl_dpy) + if (!m_egl_display) { INFO_LOG(VIDEO, "Error: eglGetDisplay() failed"); return false; } - if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) + if (!eglInitialize(m_egl_display, &egl_major, &egl_minor)) { INFO_LOG(VIDEO, "Error: eglInitialize() failed"); return false; @@ -177,12 +178,13 @@ bool cInterfaceEGL::Create(void* window_handle, bool stereo, bool core) /* Detection code */ EGLint num_configs; - DetectMode(); + if (m_opengl_mode == Mode::Detect) + DetectMode(has_handle); // attributes for a visual in RGBA format with at least // 8 bits per color int attribs[] = {EGL_RENDERABLE_TYPE, - EGL_OPENGL_ES2_BIT, + 0, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, @@ -190,43 +192,38 @@ bool cInterfaceEGL::Create(void* window_handle, bool stereo, bool core) EGL_BLUE_SIZE, 8, EGL_SURFACE_TYPE, - m_has_handle ? EGL_WINDOW_BIT : 0, + has_handle ? EGL_WINDOW_BIT : 0, EGL_NONE}; std::vector<EGLint> ctx_attribs; - switch (s_opengl_mode) + switch (m_opengl_mode) { - case GLInterfaceMode::MODE_OPENGL: + case Mode::OpenGL: attribs[1] = EGL_OPENGL_BIT; ctx_attribs = {EGL_NONE}; break; - case GLInterfaceMode::MODE_OPENGLES2: - attribs[1] = EGL_OPENGL_ES2_BIT; - ctx_attribs = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; - break; - case GLInterfaceMode::MODE_OPENGLES3: - attribs[1] = (1 << 6); /* EGL_OPENGL_ES3_BIT_KHR */ + case Mode::OpenGLES: + attribs[1] = EGL_OPENGL_ES3_BIT_KHR; ctx_attribs = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE}; break; default: ERROR_LOG(VIDEO, "Unknown opengl mode set"); return false; - break; } - if (!eglChooseConfig(egl_dpy, attribs, &m_config, 1, &num_configs)) + if (!eglChooseConfig(m_egl_display, attribs, &m_config, 1, &num_configs)) { INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config"); return false; } - if (s_opengl_mode == GLInterfaceMode::MODE_OPENGL) + if (m_opengl_mode == Mode::OpenGL) eglBindAPI(EGL_OPENGL_API); else eglBindAPI(EGL_OPENGL_ES_API); std::string tmp; - std::istringstream buffer(eglQueryString(egl_dpy, EGL_EXTENSIONS)); + std::istringstream buffer(eglQueryString(m_egl_display, EGL_EXTENSIONS)); while (buffer >> tmp) { if (tmp == "EGL_KHR_surfaceless_context") @@ -235,7 +232,7 @@ bool cInterfaceEGL::Create(void* window_handle, bool stereo, bool core) supports_core_profile = true; } - if (supports_core_profile && core && s_opengl_mode == GLInterfaceMode::MODE_OPENGL) + if (supports_core_profile && core && m_opengl_mode == Mode::OpenGL) { std::array<std::pair<int, int>, 7> versions_to_try = {{ {4, 5}, @@ -259,8 +256,8 @@ bool cInterfaceEGL::Create(void* window_handle, bool stereo, bool core) EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_NONE}; - egl_ctx = eglCreateContext(egl_dpy, m_config, EGL_NO_CONTEXT, &core_attribs[0]); - if (egl_ctx) + m_egl_context = eglCreateContext(m_egl_display, m_config, EGL_NO_CONTEXT, &core_attribs[0]); + if (m_egl_context) { m_attribs = std::move(core_attribs); break; @@ -268,14 +265,14 @@ bool cInterfaceEGL::Create(void* window_handle, bool stereo, bool core) } } - if (!egl_ctx) + if (!m_egl_context) { - m_core = false; - egl_ctx = eglCreateContext(egl_dpy, m_config, EGL_NO_CONTEXT, &ctx_attribs[0]); + m_is_core_context = false; + m_egl_context = eglCreateContext(m_egl_display, m_config, EGL_NO_CONTEXT, &ctx_attribs[0]); m_attribs = std::move(ctx_attribs); } - if (!egl_ctx) + if (!m_egl_context) { INFO_LOG(VIDEO, "Error: eglCreateContext failed"); return false; @@ -289,33 +286,33 @@ bool cInterfaceEGL::Create(void* window_handle, bool stereo, bool core) return true; } -std::unique_ptr<cInterfaceBase> cInterfaceEGL::CreateSharedContext() +std::unique_ptr<GLContext> GLContextEGL::CreateSharedContext() { - std::unique_ptr<cInterfaceBase> context = std::make_unique<cInterfaceEGL>(); - if (!context->Create(this)) + std::unique_ptr<GLContextEGL> context = std::make_unique<GLContextEGL>(); + if (!context->Initialize(this)) return nullptr; return context; } -bool cInterfaceEGL::Create(cInterfaceBase* main_context) +bool GLContextEGL::Initialize(GLContext* main_context) { - cInterfaceEGL* egl_context = static_cast<cInterfaceEGL*>(main_context); + GLContextEGL* egl_context = static_cast<GLContextEGL*>(main_context); - egl_dpy = egl_context->egl_dpy; - m_core = egl_context->m_core; + m_opengl_mode = egl_context->m_opengl_mode; + m_egl_display = egl_context->m_egl_display; + m_is_core_context = egl_context->m_is_core_context; m_config = egl_context->m_config; m_supports_surfaceless = egl_context->m_supports_surfaceless; m_is_shared = true; - m_has_handle = false; - if (egl_context->GetMode() == GLInterfaceMode::MODE_OPENGL) + if (egl_context->GetMode() == Mode::OpenGL) eglBindAPI(EGL_OPENGL_API); else eglBindAPI(EGL_OPENGL_ES_API); - egl_ctx = - eglCreateContext(egl_dpy, m_config, egl_context->egl_ctx, egl_context->m_attribs.data()); - if (!egl_ctx) + m_egl_context = eglCreateContext(m_egl_display, m_config, egl_context->m_egl_context, + egl_context->m_attribs.data()); + if (!m_egl_context) { INFO_LOG(VIDEO, "Error: eglCreateContext failed 0x%04x", eglGetError()); return false; @@ -329,13 +326,13 @@ bool cInterfaceEGL::Create(cInterfaceBase* main_context) return true; } -bool cInterfaceEGL::CreateWindowSurface() +bool GLContextEGL::CreateWindowSurface() { - if (m_has_handle) + if (m_host_window) { - EGLNativeWindowType native_window = InitializePlatform(m_host_window, m_config); - egl_surf = eglCreateWindowSurface(egl_dpy, m_config, native_window, nullptr); - if (!egl_surf) + EGLNativeWindowType native_window = GetEGLNativeWindow(m_config); + m_egl_surface = eglCreateWindowSurface(m_egl_display, m_config, native_window, nullptr); + if (!m_egl_surface) { INFO_LOG(VIDEO, "Error: eglCreateWindowSurface failed"); return false; @@ -346,8 +343,8 @@ bool cInterfaceEGL::CreateWindowSurface() EGLint attrib_list[] = { EGL_NONE, }; - egl_surf = eglCreatePbufferSurface(egl_dpy, m_config, attrib_list); - if (!egl_surf) + m_egl_surface = eglCreatePbufferSurface(m_egl_display, m_config, attrib_list); + if (!m_egl_surface) { INFO_LOG(VIDEO, "Error: eglCreatePbufferSurface failed"); return false; @@ -355,56 +352,50 @@ bool cInterfaceEGL::CreateWindowSurface() } else { - egl_surf = EGL_NO_SURFACE; + m_egl_surface = EGL_NO_SURFACE; } return true; } -void cInterfaceEGL::DestroyWindowSurface() +void GLContextEGL::DestroyWindowSurface() { - if (egl_surf != EGL_NO_SURFACE && !eglDestroySurface(egl_dpy, egl_surf)) + if (m_egl_surface != EGL_NO_SURFACE && !eglDestroySurface(m_egl_display, m_egl_surface)) 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); + m_egl_surface = EGL_NO_SURFACE; } -void cInterfaceEGL::UpdateHandle(void* window_handle) +bool GLContextEGL::MakeCurrent() { - m_host_window = (EGLNativeWindowType)window_handle; - m_has_handle = !!window_handle; + return eglMakeCurrent(m_egl_display, m_egl_surface, m_egl_surface, m_egl_context); } -void cInterfaceEGL::UpdateSurface() +void GLContextEGL::UpdateSurface(void* window_handle) { + m_host_window = window_handle; ClearCurrent(); DestroyWindowSurface(); CreateWindowSurface(); MakeCurrent(); } -bool cInterfaceEGL::ClearCurrent() +bool GLContextEGL::ClearCurrent() { - return eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + return eglMakeCurrent(m_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); } // Close backend -void cInterfaceEGL::Shutdown() +void GLContextEGL::Shutdown() { - ShutdownPlatform(); - if (egl_ctx) + if (m_egl_context) { - if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) + if (!eglMakeCurrent(m_egl_display, m_egl_surface, m_egl_surface, m_egl_context)) 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)) + eglMakeCurrent(m_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (!eglDestroyContext(m_egl_display, m_egl_context)) NOTICE_LOG(VIDEO, "Could not destroy drawing context."); DestroyWindowSurface(); - if (!m_is_shared && !eglTerminate(egl_dpy)) + if (!m_is_shared && !eglTerminate(m_egl_display)) NOTICE_LOG(VIDEO, "Could not destroy display connection."); - egl_ctx = nullptr; + m_egl_context = nullptr; } } |
