mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Intercept EGL query and remove unsupported extensions. Closes #2830
* Since EGL is an Android API and highly likely to have unstable/unsupported/internal extensions, and also because we for the most part pass through the API apart from a couple of functions that we intercept but don't need to fully understand or process the attributes of, we take the approach of removing problematic extensions rather than only allowing extensions we know are safe.
This commit is contained in:
@@ -79,6 +79,7 @@ typedef PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC PFN_eglSwapBuffersWithDamageKHR;
|
||||
FUNC(CreatePlatformWindowSurface, false, false); \
|
||||
FUNC(MakeCurrent, false, true); \
|
||||
FUNC(SwapBuffers, false, true); \
|
||||
FUNC(QueryString, false, true); \
|
||||
FUNC(PostSubBufferNV, true, false); \
|
||||
FUNC(SwapBuffersWithDamageEXT, true, false); \
|
||||
FUNC(SwapBuffersWithDamageKHR, true, false);
|
||||
@@ -94,7 +95,6 @@ typedef PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC PFN_eglSwapBuffersWithDamageKHR;
|
||||
FUNC(GetError, false, true); \
|
||||
FUNC(Initialize, false, true); \
|
||||
FUNC(QueryAPI, false, true); \
|
||||
FUNC(QueryString, false, true); \
|
||||
FUNC(QuerySurface, false, true); \
|
||||
FUNC(QueryContext, false, true);
|
||||
|
||||
|
||||
@@ -22,10 +22,17 @@
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "core/settings.h"
|
||||
#include "hooks/hooks.h"
|
||||
#include "strings/string_utils.h"
|
||||
#include "egl_dispatch_table.h"
|
||||
#include "gl_driver.h"
|
||||
|
||||
RDOC_CONFIG(bool, Android_AllowAllEGLExtensions, false,
|
||||
"Normally certain extensions are removed from the EGL extension string for "
|
||||
"compatibility, but with this option that behaviour can be overridden and all "
|
||||
"extensions will be reported.");
|
||||
|
||||
#if ENABLED(RDOC_POSIX)
|
||||
#include <dlfcn.h>
|
||||
|
||||
@@ -59,6 +66,11 @@ class EGLHook : LibraryHook
|
||||
{
|
||||
public:
|
||||
EGLHook() : driver(GetEGLPlatform()) {}
|
||||
~EGLHook()
|
||||
{
|
||||
for(auto it : extStrings)
|
||||
SAFE_DELETE(it.second);
|
||||
}
|
||||
void RegisterHooks();
|
||||
|
||||
RDCDriver activeAPI = RDCDriver::OpenGLES;
|
||||
@@ -69,6 +81,7 @@ public:
|
||||
std::map<EGLContext, EGLConfig> configs;
|
||||
std::map<EGLSurface, SurfaceConfig> windows;
|
||||
std::map<EGLDisplay, DisplayConfig> displays;
|
||||
std::map<EGLDisplay, rdcstr *> extStrings;
|
||||
|
||||
// indicates we're in a swap function, so don't process the swap any further if we recurse - could
|
||||
// happen due to driver implementation of one function calling another
|
||||
@@ -551,6 +564,45 @@ HOOK_EXPORT EGLBoolean EGLAPIENTRY eglSwapBuffers_renderdoc_hooked(EGLDisplay dp
|
||||
}
|
||||
}
|
||||
|
||||
HOOK_EXPORT const char *EGLAPIENTRY eglQueryString_renderdoc_hooked(EGLDisplay dpy, EGLint name)
|
||||
{
|
||||
if(RenderDoc::Inst().IsReplayApp())
|
||||
{
|
||||
if(!EGL.QueryString)
|
||||
EGL.PopulateForReplay();
|
||||
|
||||
return EGL.QueryString(dpy, name);
|
||||
}
|
||||
|
||||
EnsureRealLibraryLoaded();
|
||||
|
||||
SCOPED_LOCK(glLock);
|
||||
|
||||
if(name == EGL_EXTENSIONS && !Android_AllowAllEGLExtensions())
|
||||
{
|
||||
rdcstr *extStr = eglhook.extStrings[dpy];
|
||||
if(extStr == NULL)
|
||||
extStr = eglhook.extStrings[dpy] = new rdcstr;
|
||||
|
||||
const rdcstr implExtStr = EGL.QueryString(dpy, name);
|
||||
|
||||
rdcarray<rdcstr> exts;
|
||||
split(implExtStr, exts, ' ');
|
||||
|
||||
// We take the unusual approach here of explicitly _disallowing_ extensions only when we know
|
||||
// they are unsupported. The main reason for this is because EGL is the android platform API and
|
||||
// it may well be that undocumented internal or private extensions are important and should not
|
||||
// be filtered out. Also since we have minimal interaction with the API as long as they don't
|
||||
// affect the functions we care about for context management and swapping most extensions can be
|
||||
// allowed silently.
|
||||
exts.removeOne("EGL_KHR_no_config_context");
|
||||
|
||||
merge(exts, *extStr, ' ');
|
||||
}
|
||||
|
||||
return EGL.QueryString(dpy, name);
|
||||
}
|
||||
|
||||
HOOK_EXPORT EGLBoolean EGLAPIENTRY eglPostSubBufferNV_renderdoc_hooked(EGLDisplay dpy,
|
||||
EGLSurface surface, EGLint x,
|
||||
EGLint y, EGLint width,
|
||||
@@ -752,6 +804,11 @@ HOOK_EXPORT EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface sur
|
||||
return eglSwapBuffers_renderdoc_hooked(dpy, surface);
|
||||
}
|
||||
|
||||
HOOK_EXPORT const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
|
||||
{
|
||||
return eglQueryString_renderdoc_hooked(dpy, name);
|
||||
}
|
||||
|
||||
HOOK_EXPORT EGLBoolean EGLAPIENTRY eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x,
|
||||
EGLint y, EGLint width, EGLint height)
|
||||
{
|
||||
@@ -866,7 +923,6 @@ EGL_PASSTHRU_0(EGLint, eglGetError)
|
||||
EGL_PASSTHRU_3(EGLBoolean, eglInitialize, EGLDisplay, dpy, EGLint *, major, EGLint *, minor)
|
||||
EGL_PASSTHRU_4(EGLBoolean, eglQueryContext, EGLDisplay, dpy, EGLContext, ctx, EGLint, attribute,
|
||||
EGLint *, value)
|
||||
EGL_PASSTHRU_2(const char *, eglQueryString, EGLDisplay, dpy, EGLint, name)
|
||||
EGL_PASSTHRU_4(EGLBoolean, eglQuerySurface, EGLDisplay, dpy, EGLSurface, surface, EGLint, attribute,
|
||||
EGLint *, value)
|
||||
EGL_PASSTHRU_1(EGLBoolean, eglTerminate, EGLDisplay, dpy)
|
||||
|
||||
Reference in New Issue
Block a user