From a53797fc5122a5930f40b591a9f056c88f7f2485 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 6 Jul 2018 20:42:55 +0100 Subject: [PATCH] Remap EGLSurface back to native window pointer * We need the native window pointer for registering frame capturers, and adding input window filters (on windows). --- renderdoc/driver/gl/egl_dispatch_table.h | 16 +++++------ renderdoc/driver/gl/egl_hooks.cpp | 35 ++++++++++++++++++++++-- renderdoc/driver/gl/egl_platform.cpp | 3 +- renderdoc/driver/gl/gl_common.cpp | 2 ++ renderdoc/driver/gl/gl_common.h | 28 +++++++------------ renderdoc/driver/gl/gl_outputwindow.cpp | 4 +-- 6 files changed, 57 insertions(+), 31 deletions(-) diff --git a/renderdoc/driver/gl/egl_dispatch_table.h b/renderdoc/driver/gl/egl_dispatch_table.h index 09dc18330..79039ab38 100644 --- a/renderdoc/driver/gl/egl_dispatch_table.h +++ b/renderdoc/driver/gl/egl_dispatch_table.h @@ -53,20 +53,20 @@ typedef EGLBoolean (*PFN_eglGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, E EGLint *value); typedef PFNEGLPOSTSUBBUFFERNVPROC PFN_eglPostSubBufferNV; -#define EGL_HOOKED_SYMBOLS(FUNC) \ - FUNC(GetDisplay, false); \ - FUNC(CreateContext, false); \ - FUNC(DestroyContext, false); \ - FUNC(MakeCurrent, false); \ - FUNC(SwapBuffers, false); \ - FUNC(GetProcAddress, false); \ +#define EGL_HOOKED_SYMBOLS(FUNC) \ + FUNC(GetDisplay, false); \ + FUNC(CreateContext, false); \ + FUNC(DestroyContext, false); \ + FUNC(CreateWindowSurface, false); \ + FUNC(MakeCurrent, false); \ + FUNC(SwapBuffers, false); \ + FUNC(GetProcAddress, false); \ FUNC(PostSubBufferNV, true); #define EGL_NONHOOKED_SYMBOLS(FUNC) \ FUNC(BindAPI, false); \ FUNC(ChooseConfig, false); \ FUNC(CreatePbufferSurface, false); \ - FUNC(CreateWindowSurface, false); \ FUNC(DestroySurface, false); \ FUNC(GetConfigAttrib, false); \ FUNC(GetCurrentContext, false); \ diff --git a/renderdoc/driver/gl/egl_hooks.cpp b/renderdoc/driver/gl/egl_hooks.cpp index a5f91b8a9..07b7fab96 100644 --- a/renderdoc/driver/gl/egl_hooks.cpp +++ b/renderdoc/driver/gl/egl_hooks.cpp @@ -52,6 +52,7 @@ public: WrappedOpenGL driver; std::set contexts; std::map configs; + std::map windows; } eglhook; HOOK_EXPORT EGLDisplay eglGetDisplay(EGLNativeDisplayType display) @@ -164,6 +165,7 @@ HOOK_EXPORT EGLContext eglCreateContext(EGLDisplay display, EGLConfig config, GLWindowingData data; data.egl_dpy = display; + data.wnd = 0; data.egl_wnd = (EGLSurface)NULL; data.egl_ctx = ret; data.egl_cfg = config; @@ -199,6 +201,29 @@ HOOK_EXPORT EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) return EGL.DestroyContext(dpy, ctx); } +HOOK_EXPORT EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, + EGLNativeWindowType win, const EGLint *attrib_list) +{ + if(RenderDoc::Inst().IsReplayApp()) + { + if(!EGL.CreateWindowSurface) + EGL.PopulateForReplay(); + + return EGL.CreateWindowSurface(dpy, config, win, attrib_list); + } + + EGLSurface ret = EGL.CreateWindowSurface(dpy, config, win, attrib_list); + + if(ret) + { + SCOPED_LOCK(glLock); + + eglhook.windows[ret] = win; + } + + return ret; +} + HOOK_EXPORT EGLBoolean eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext ctx) { @@ -234,6 +259,14 @@ HOOK_EXPORT EGLBoolean eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSu data.egl_dpy = display; data.egl_wnd = draw; data.egl_ctx = ctx; + data.wnd = eglhook.windows[draw]; + + if(!data.wnd) + { + // could be a pbuffer surface or other offscreen rendering. We want a valid wnd, so set it to + // a dummy value + data.wnd = (decltype(data.wnd))(void *)(uintptr_t(0xdeadbeef) + uintptr_t(draw)); + } // we could query this out technically but it's easier to keep a map data.egl_cfg = eglhook.configs[ctx]; @@ -423,8 +456,6 @@ EGL_PASSTHRU_3(EGLSurface, eglCreatePbufferSurface, EGLDisplay, dpy, EGLConfig, const EGLint *, attrib_list) EGL_PASSTHRU_4(EGLSurface, eglCreatePixmapSurface, EGLDisplay, dpy, EGLConfig, config, EGLNativePixmapType, pixmap, const EGLint *, attrib_list) -EGL_PASSTHRU_4(EGLSurface, eglCreateWindowSurface, EGLDisplay, dpy, EGLConfig, config, - EGLNativeWindowType, win, const EGLint *, attrib_list) EGL_PASSTHRU_2(EGLBoolean, eglDestroySurface, EGLDisplay, dpy, EGLSurface, surface) EGL_PASSTHRU_4(EGLBoolean, eglGetConfigAttrib, EGLDisplay, dpy, EGLConfig, config, EGLint, attribute, EGLint *, value) diff --git a/renderdoc/driver/gl/egl_platform.cpp b/renderdoc/driver/gl/egl_platform.cpp index d72d55144..7d1bd4f93 100644 --- a/renderdoc/driver/gl/egl_platform.cpp +++ b/renderdoc/driver/gl/egl_platform.cpp @@ -226,6 +226,7 @@ class EGLPlatform : public GLPlatform RDCERR("Couldn't create a suitable PBuffer"); } + ret.wnd = window; ret.egl_wnd = surface; return ret; @@ -257,7 +258,7 @@ class EGLPlatform : public GLPlatform replayContext = CreateWindowingData(eglDisplay, EGL_NO_CONTEXT, 0); - if(!replayContext.ctx || !replayContext.wnd) + if(!replayContext.ctx) { RDCERR("Couldn't create OpenGL ES 3.x replay context - required for replay"); DeleteReplayContext(replayContext); diff --git a/renderdoc/driver/gl/gl_common.cpp b/renderdoc/driver/gl/gl_common.cpp index 1bec250f2..284faf3e7 100644 --- a/renderdoc/driver/gl/gl_common.cpp +++ b/renderdoc/driver/gl/gl_common.cpp @@ -943,6 +943,8 @@ void GLPushPopState::Push(bool modern) GL.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO); } + + ClearGLErrors(); } void GLPushPopState::Pop(bool modern) diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 40ceec691..52cffd568 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -106,11 +106,8 @@ struct GLWindowingData HGLRC ctx; EGLContext egl_ctx; }; - union - { - HWND wnd; - EGLSurface egl_wnd; - }; + HWND wnd; + EGLSurface egl_wnd; EGLConfig egl_cfg; }; @@ -185,15 +182,12 @@ struct GLWindowingData GLESContextPtr egl_ctx; }; union - { - GLWindowPtr wnd; - GLESWindowPtr egl_wnd; - }; - union { GLConfigPtr cfg; GLESConfigPtr egl_cfg; }; + GLWindowPtr wnd; + GLESWindowPtr egl_wnd; }; #elif ENABLED(RDOC_APPLE) @@ -224,9 +218,10 @@ struct GLWindowingData { GLWindowingData() { - egl_ctx = 0; - egl_dpy = 0; - egl_wnd = 0; + egl_ctx = NULL; + egl_dpy = NULL; + wnd = NULL; + egl_wnd = NULL; } union @@ -235,11 +230,8 @@ struct GLWindowingData void *ctx; EGLContext egl_ctx; }; - union - { - EGLSurface egl_wnd; - void *wnd; - }; + EGLSurface egl_wnd; + void *wnd; EGLDisplay egl_dpy; EGLConfig egl_cfg; }; diff --git a/renderdoc/driver/gl/gl_outputwindow.cpp b/renderdoc/driver/gl/gl_outputwindow.cpp index 302e0a203..4276f7193 100644 --- a/renderdoc/driver/gl/gl_outputwindow.cpp +++ b/renderdoc/driver/gl/gl_outputwindow.cpp @@ -100,7 +100,7 @@ bool GLReplay::CheckResizeOutputWindow(uint64_t id) OutputWindow &outw = m_OutputWindows[id]; - if(outw.wnd == 0) + if(outw.ctx == 0) return false; int32_t w, h; @@ -205,7 +205,7 @@ void GLReplay::FlipOutputWindow(uint64_t id) uint64_t GLReplay::MakeOutputWindow(WindowingData window, bool depth) { OutputWindow win = m_pDriver->m_Platform.MakeOutputWindow(window, depth, m_ReplayCtx); - if(!win.wnd) + if(!win.ctx) return 0; m_pDriver->m_Platform.GetOutputWindowDimensions(win, win.width, win.height);