mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 01:20:42 +00:00
Add EGL replay implementation
This commit is contained in:
committed by
Baldur Karlsson
parent
af6b4cf68c
commit
a70bcb8ad3
@@ -65,6 +65,12 @@ struct GLWindowingData
|
||||
#include "official/glxext.h"
|
||||
#endif
|
||||
#if RENDERDOC_SUPPORT_GLES
|
||||
|
||||
// force include the elgplatform.h, as we want to use
|
||||
// our own because the system one could be a bit older and
|
||||
// propably not suitable for the given egl.h
|
||||
#include "official/eglplatform.h"
|
||||
|
||||
#include "official/egl.h"
|
||||
#include "official/eglext.h"
|
||||
#endif
|
||||
|
||||
@@ -27,26 +27,152 @@
|
||||
#include "gl_driver.h"
|
||||
#include "gl_resources.h"
|
||||
|
||||
typedef EGLBoolean (*PFN_eglBindAPI)(EGLenum api);
|
||||
typedef EGLDisplay (*PFN_eglGetDisplay)(EGLNativeDisplayType display_id);
|
||||
typedef EGLContext (*PFN_eglCreateContext)(EGLDisplay dpy, EGLConfig config,
|
||||
EGLContext share_context, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (*PFN_eglMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
|
||||
EGLContext ctx);
|
||||
typedef EGLBoolean (*PFN_eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
|
||||
typedef EGLBoolean (*PFN_eglDestroyContext)(EGLDisplay dpy, EGLContext ctx);
|
||||
typedef EGLBoolean (*PFN_eglQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute,
|
||||
EGLint *value);
|
||||
typedef EGLBoolean (*PFN_eglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
|
||||
typedef EGLSurface (*PFN_eglCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config,
|
||||
const EGLint *attrib_list);
|
||||
typedef EGLSurface (*PFN_eglCreateWindowSurface)(EGLDisplay dpy, EGLConfig config,
|
||||
EGLNativeWindowType win, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (*PFN_eglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list,
|
||||
EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
||||
typedef __eglMustCastToProperFunctionPointerType (*PFN_eglGetProcAddress)(const char *procname);
|
||||
typedef EGLBoolean (*PFN_eglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
|
||||
|
||||
PFN_eglBindAPI eglBindAPIProc = NULL;
|
||||
PFN_eglInitialize eglInitializeProc = NULL;
|
||||
PFN_eglGetDisplay eglGetDisplayProc = NULL;
|
||||
PFN_eglCreateContext eglCreateContextProc = NULL;
|
||||
PFN_eglMakeCurrent eglMakeCurrentProc = NULL;
|
||||
PFN_eglSwapBuffers eglSwapBuffersProc = NULL;
|
||||
PFN_eglDestroyContext eglDestroyContextProc = NULL;
|
||||
PFN_eglQuerySurface eglQuerySurfaceProc = NULL;
|
||||
PFN_eglDestroySurface eglDestroySurfaceProc = NULL;
|
||||
PFN_eglCreatePbufferSurface eglCreatePbufferSurfaceProc = NULL;
|
||||
PFN_eglCreateWindowSurface eglCreateWindowSurfaceProc = NULL;
|
||||
PFN_eglChooseConfig eglChooseConfigProc = NULL;
|
||||
PFN_eglGetProcAddress eglGetProcAddressProc = NULL;
|
||||
|
||||
void GLReplay::MakeCurrentReplayContext(GLWindowingData *ctx)
|
||||
{
|
||||
// TODO
|
||||
static GLWindowingData *prev = NULL;
|
||||
|
||||
if(eglMakeCurrentProc && ctx && ctx != prev)
|
||||
{
|
||||
prev = ctx;
|
||||
eglMakeCurrentProc(ctx->egl_dpy, ctx->egl_wnd, ctx->egl_wnd, ctx->egl_ctx);
|
||||
m_pDriver->ActivateContext(*ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void GLReplay::SwapBuffers(GLWindowingData *ctx)
|
||||
{
|
||||
// TODO
|
||||
eglSwapBuffersProc(ctx->egl_dpy, ctx->egl_wnd);
|
||||
}
|
||||
|
||||
void GLReplay::CloseReplayContext()
|
||||
{
|
||||
// TODO
|
||||
if(eglDestroyContextProc)
|
||||
{
|
||||
eglMakeCurrentProc(m_ReplayCtx.egl_dpy, 0L, 0L, NULL);
|
||||
eglDestroyContextProc(m_ReplayCtx.egl_dpy, m_ReplayCtx.egl_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t GLReplay::MakeOutputWindow(WindowingSystem system, void *data, bool depth)
|
||||
{
|
||||
// TODO
|
||||
EGLNativeWindowType window = 0;
|
||||
|
||||
if(system == eWindowingSystem_Xlib)
|
||||
{
|
||||
XlibWindowData *xlib = (XlibWindowData *)data;
|
||||
window = (EGLNativeWindowType)xlib->window;
|
||||
}
|
||||
else if(system == eWindowingSystem_Unknown)
|
||||
{
|
||||
// allow undefined so that internally we can create a window-less context
|
||||
Display *dpy = XOpenDisplay(NULL);
|
||||
|
||||
if(dpy == NULL)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected window system %u", system);
|
||||
}
|
||||
|
||||
EGLDisplay eglDisplay = eglGetDisplayProc(EGL_DEFAULT_DISPLAY);
|
||||
RDCASSERT(eglDisplay);
|
||||
|
||||
static const EGLint configAttribs[] = {EGL_RED_SIZE,
|
||||
8,
|
||||
EGL_GREEN_SIZE,
|
||||
8,
|
||||
EGL_BLUE_SIZE,
|
||||
8,
|
||||
EGL_RENDERABLE_TYPE,
|
||||
EGL_OPENGL_ES3_BIT,
|
||||
EGL_SURFACE_TYPE,
|
||||
EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
|
||||
EGL_NONE};
|
||||
EGLint numConfigs;
|
||||
EGLConfig config;
|
||||
|
||||
if(!eglChooseConfigProc(eglDisplay, configAttribs, &config, 1, &numConfigs))
|
||||
{
|
||||
RDCERR("Couldn't find a suitable EGL config");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const EGLint ctxAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_CONTEXT_FLAGS_KHR,
|
||||
EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL_NONE};
|
||||
|
||||
EGLContext ctx = eglCreateContextProc(eglDisplay, config, EGL_NO_CONTEXT, ctxAttribs);
|
||||
|
||||
if(ctx == NULL)
|
||||
{
|
||||
RDCERR("Couldn't create GL ES context");
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLSurface surface = 0;
|
||||
|
||||
if(window != 0)
|
||||
{
|
||||
surface = eglCreateWindowSurfaceProc(eglDisplay, config, window, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
static const EGLint pbAttribs[] = {EGL_WIDTH, 32, EGL_HEIGHT, 32, EGL_NONE};
|
||||
surface = eglCreatePbufferSurfaceProc(eglDisplay, config, pbAttribs);
|
||||
}
|
||||
|
||||
RDCASSERT(surface != NULL);
|
||||
|
||||
OutputWindow win;
|
||||
win.egl_dpy = eglDisplay;
|
||||
win.egl_ctx = ctx;
|
||||
win.egl_wnd = surface;
|
||||
|
||||
eglQuerySurfaceProc(eglDisplay, surface, EGL_WIDTH, &win.width);
|
||||
eglQuerySurfaceProc(eglDisplay, surface, EGL_HEIGHT, &win.height);
|
||||
|
||||
MakeCurrentReplayContext(&win);
|
||||
InitOutputWindow(win);
|
||||
CreateOutputWindowBackbuffer(win, depth);
|
||||
|
||||
uint64_t ret = m_OutputWindowID++;
|
||||
|
||||
m_OutputWindows[ret] = win;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -63,9 +189,10 @@ void GLReplay::DestroyOutputWindow(uint64_t id)
|
||||
WrappedOpenGL &gl = *m_pDriver;
|
||||
gl.glDeleteFramebuffers(1, &outw.BlitData.readFBO);
|
||||
|
||||
m_OutputWindows.erase(it);
|
||||
eglMakeCurrentProc(outw.egl_dpy, 0L, 0L, NULL);
|
||||
eglDestroyContextProc(outw.egl_dpy, outw.egl_ctx);
|
||||
|
||||
// TODO
|
||||
m_OutputWindows.erase(it);
|
||||
}
|
||||
|
||||
void GLReplay::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h)
|
||||
@@ -75,7 +202,8 @@ void GLReplay::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h)
|
||||
|
||||
OutputWindow &outw = m_OutputWindows[id];
|
||||
|
||||
// TODO
|
||||
eglQuerySurfaceProc(outw.egl_dpy, outw.egl_wnd, EGL_WIDTH, &w);
|
||||
eglQuerySurfaceProc(outw.egl_dpy, outw.egl_wnd, EGL_HEIGHT, &h);
|
||||
}
|
||||
|
||||
bool GLReplay::IsOutputWindowVisible(uint64_t id)
|
||||
@@ -94,6 +222,159 @@ ReplayCreateStatus GL_CreateReplayDevice(const char *logfile, IReplayDriver **dr
|
||||
{
|
||||
RDCDEBUG("Creating an OpenGL ES replay device");
|
||||
|
||||
// TODO
|
||||
return eReplayCreate_APIInitFailed;
|
||||
// Query the required EGL functions
|
||||
if(eglCreateContextProc == NULL)
|
||||
{
|
||||
eglGetProcAddressProc = (PFN_eglGetProcAddress)dlsym(RTLD_NEXT, "eglGetProcAddress");
|
||||
eglChooseConfigProc = (PFN_eglChooseConfig)dlsym(RTLD_NEXT, "eglChooseConfig");
|
||||
eglInitializeProc = (PFN_eglInitialize)dlsym(RTLD_NEXT, "eglInitialize");
|
||||
eglBindAPIProc = (PFN_eglBindAPI)dlsym(RTLD_NEXT, "eglBindAPI");
|
||||
eglGetDisplayProc = (PFN_eglGetDisplay)dlsym(RTLD_NEXT, "eglGetDisplay");
|
||||
eglCreateContextProc = (PFN_eglCreateContext)dlsym(RTLD_NEXT, "eglCreateContext");
|
||||
eglMakeCurrentProc = (PFN_eglMakeCurrent)dlsym(RTLD_NEXT, "eglMakeCurrent");
|
||||
eglSwapBuffersProc = (PFN_eglSwapBuffers)dlsym(RTLD_NEXT, "eglSwapBuffers");
|
||||
eglDestroyContextProc = (PFN_eglDestroyContext)dlsym(RTLD_NEXT, "eglDestroyContext");
|
||||
eglDestroySurfaceProc = (PFN_eglDestroySurface)dlsym(RTLD_NEXT, "eglDestroySurface");
|
||||
eglQuerySurfaceProc = (PFN_eglQuerySurface)dlsym(RTLD_NEXT, "eglQuerySurface");
|
||||
eglCreatePbufferSurfaceProc =
|
||||
(PFN_eglCreatePbufferSurface)dlsym(RTLD_NEXT, "eglCreatePbufferSurface");
|
||||
eglCreateWindowSurfaceProc =
|
||||
(PFN_eglCreateWindowSurface)dlsym(RTLD_NEXT, "eglCreateWindowSurface");
|
||||
|
||||
if(eglGetProcAddressProc == NULL || eglBindAPIProc == NULL || eglGetDisplayProc == NULL ||
|
||||
eglCreateContextProc == NULL || eglMakeCurrentProc == NULL || eglSwapBuffersProc == NULL ||
|
||||
eglDestroyContextProc == NULL || eglDestroySurfaceProc == NULL ||
|
||||
eglQuerySurfaceProc == NULL || eglCreatePbufferSurfaceProc == NULL ||
|
||||
eglCreateWindowSurfaceProc == NULL || eglChooseConfigProc == NULL)
|
||||
{
|
||||
RDCERR(
|
||||
"Couldn't find required function addresses, eglGetProcAddress eglCreateContext"
|
||||
"eglSwapBuffers (etc.)");
|
||||
return eReplayCreate_APIInitFailed;
|
||||
}
|
||||
}
|
||||
|
||||
GLInitParams initParams;
|
||||
RDCDriver driverType = RDC_OpenGL;
|
||||
string driverName = "OpenGL";
|
||||
uint64_t machineIdent = 0;
|
||||
|
||||
if(logfile)
|
||||
{
|
||||
auto status = RenderDoc::Inst().FillInitParams(logfile, driverType, driverName, machineIdent,
|
||||
(RDCInitParams *)&initParams);
|
||||
if(status != eReplayCreate_Success)
|
||||
return status;
|
||||
}
|
||||
|
||||
Display *dpy = XOpenDisplay(NULL);
|
||||
|
||||
if(dpy == NULL)
|
||||
{
|
||||
RDCERR("Couldn't open default X display");
|
||||
return eReplayCreate_APIInitFailed;
|
||||
}
|
||||
|
||||
eglBindAPIProc(EGL_OPENGL_ES_API);
|
||||
|
||||
EGLDisplay eglDisplay = eglGetDisplayProc(EGL_DEFAULT_DISPLAY);
|
||||
if(!eglDisplay)
|
||||
{
|
||||
RDCERR("Couldn't open default EGL display");
|
||||
return eReplayCreate_APIInitFailed;
|
||||
}
|
||||
|
||||
int major, minor;
|
||||
eglInitializeProc(eglDisplay, &major, &minor);
|
||||
|
||||
static const EGLint configAttribs[] = {EGL_RED_SIZE,
|
||||
8,
|
||||
EGL_GREEN_SIZE,
|
||||
8,
|
||||
EGL_BLUE_SIZE,
|
||||
8,
|
||||
EGL_RENDERABLE_TYPE,
|
||||
EGL_OPENGL_ES3_BIT,
|
||||
EGL_SURFACE_TYPE,
|
||||
EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
|
||||
EGL_NONE};
|
||||
EGLint numConfigs;
|
||||
EGLConfig config;
|
||||
|
||||
if(!eglChooseConfigProc(eglDisplay, configAttribs, &config, 1, &numConfigs))
|
||||
{
|
||||
RDCERR("Couldn't find a suitable EGL config");
|
||||
return eReplayCreate_APIInitFailed;
|
||||
}
|
||||
|
||||
static const EGLint ctxAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_CONTEXT_FLAGS_KHR,
|
||||
EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL_NONE};
|
||||
|
||||
GLReplay::PreContextInitCounters();
|
||||
|
||||
EGLContext ctx = eglCreateContextProc(eglDisplay, config, EGL_NO_CONTEXT, ctxAttribs);
|
||||
if(ctx == NULL)
|
||||
{
|
||||
XCloseDisplay(dpy);
|
||||
GLReplay::PostContextShutdownCounters();
|
||||
RDCERR("Couldn't create GL ES 3.x context - RenderDoc requires OpenGL ES 3.x availability");
|
||||
return eReplayCreate_APIHardwareUnsupported;
|
||||
}
|
||||
|
||||
static const EGLint pbAttribs[] = {EGL_WIDTH, 32, EGL_HEIGHT, 32, EGL_NONE};
|
||||
EGLSurface pbuffer = eglCreatePbufferSurfaceProc(eglDisplay, config, pbAttribs);
|
||||
|
||||
if(pbuffer == NULL)
|
||||
{
|
||||
RDCERR("Couldn't create a suitable PBuffer");
|
||||
eglDestroySurfaceProc(eglDisplay, pbuffer);
|
||||
XCloseDisplay(dpy);
|
||||
GLReplay::PostContextShutdownCounters();
|
||||
return eReplayCreate_APIInitFailed;
|
||||
}
|
||||
|
||||
EGLBoolean res = eglMakeCurrentProc(eglDisplay, pbuffer, pbuffer, ctx);
|
||||
if(!res)
|
||||
{
|
||||
RDCERR("Couldn't active the created GL ES context");
|
||||
eglDestroySurfaceProc(eglDisplay, pbuffer);
|
||||
eglDestroyContextProc(eglDisplay, ctx);
|
||||
XCloseDisplay(dpy);
|
||||
GLReplay::PostContextShutdownCounters();
|
||||
return eReplayCreate_APIInitFailed;
|
||||
}
|
||||
|
||||
// TODO: add extesion check just like in the GL case.
|
||||
|
||||
const GLHookSet &real = GetRealGLFunctionsEGL();
|
||||
bool extensionsValidated = ValidateFunctionPointers(real);
|
||||
if(!extensionsValidated)
|
||||
{
|
||||
eglDestroySurfaceProc(eglDisplay, pbuffer);
|
||||
eglDestroyContextProc(eglDisplay, ctx);
|
||||
XCloseDisplay(dpy);
|
||||
GLReplay::PostContextShutdownCounters();
|
||||
return eReplayCreate_APIHardwareUnsupported;
|
||||
}
|
||||
|
||||
WrappedOpenGL *gl = new WrappedOpenGL(logfile, real);
|
||||
gl->Initialise(initParams);
|
||||
|
||||
if(gl->GetSerialiser()->HasError())
|
||||
{
|
||||
delete gl;
|
||||
return eReplayCreate_FileIOFailed;
|
||||
}
|
||||
|
||||
RDCLOG("Created OPEN GL ES replay device.");
|
||||
GLReplay *replay = gl->GetReplay();
|
||||
replay->SetProxy(logfile == NULL);
|
||||
GLWindowingData data;
|
||||
data.egl_dpy = eglDisplay;
|
||||
data.egl_ctx = ctx;
|
||||
data.egl_wnd = pbuffer;
|
||||
replay->SetReplayData(data);
|
||||
|
||||
*driver = (IReplayDriver *)replay;
|
||||
return eReplayCreate_Success;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
#ifndef __eglplatform_h_
|
||||
#define __eglplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2007-2016 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Platform-specific types and definitions for egl.h
|
||||
* $Revision: 30994 $ on $Date: 2015-04-30 13:36:48 -0700 (Thu, 30 Apr 2015) $
|
||||
*
|
||||
* Adopters may modify khrplatform.h and this file to suit their platform.
|
||||
* You are encouraged to submit all modifications to the Khronos group so that
|
||||
* they can be included in future versions of this file. Please submit changes
|
||||
* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
|
||||
* by filing a bug against product "EGL" component "Registry".
|
||||
*/
|
||||
|
||||
#include <KHR/khrplatform.h>
|
||||
|
||||
/* Macros used in EGL function prototype declarations.
|
||||
*
|
||||
* EGL functions should be prototyped as:
|
||||
*
|
||||
* EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
|
||||
* typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments);
|
||||
*
|
||||
* KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h
|
||||
*/
|
||||
|
||||
#ifndef EGLAPI
|
||||
#define EGLAPI KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
#ifndef EGLAPIENTRY
|
||||
#define EGLAPIENTRY KHRONOS_APIENTRY
|
||||
#endif
|
||||
#define EGLAPIENTRYP EGLAPIENTRY*
|
||||
|
||||
/* The types NativeDisplayType, NativeWindowType, and NativePixmapType
|
||||
* are aliases of window-system-dependent types, such as X Display * or
|
||||
* Windows Device Context. They must be defined in platform-specific
|
||||
* code below. The EGL-prefixed versions of Native*Type are the same
|
||||
* types, renamed in EGL 1.3 so all types in the API start with "EGL".
|
||||
*
|
||||
* Khronos STRONGLY RECOMMENDS that you use the default definitions
|
||||
* provided below, since these changes affect both binary and source
|
||||
* portability of applications using EGL running on different EGL
|
||||
* implementations.
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
typedef HDC EGLNativeDisplayType;
|
||||
typedef HBITMAP EGLNativePixmapType;
|
||||
typedef HWND EGLNativeWindowType;
|
||||
|
||||
#elif defined(__APPLE__) || defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
|
||||
|
||||
typedef int EGLNativeDisplayType;
|
||||
typedef void *EGLNativeWindowType;
|
||||
typedef void *EGLNativePixmapType;
|
||||
|
||||
#elif defined(__ANDROID__) || defined(ANDROID)
|
||||
|
||||
#include <android/native_window.h>
|
||||
|
||||
struct egl_native_pixmap_t;
|
||||
|
||||
typedef struct ANativeWindow* EGLNativeWindowType;
|
||||
typedef struct egl_native_pixmap_t* EGLNativePixmapType;
|
||||
typedef void* EGLNativeDisplayType;
|
||||
|
||||
#elif defined(__unix__)
|
||||
|
||||
/* X11 (tentative) */
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
typedef Display *EGLNativeDisplayType;
|
||||
typedef Pixmap EGLNativePixmapType;
|
||||
typedef Window EGLNativeWindowType;
|
||||
|
||||
#else
|
||||
#error "Platform not recognized"
|
||||
#endif
|
||||
|
||||
/* EGL 1.2 types, renamed for consistency in EGL 1.3 */
|
||||
typedef EGLNativeDisplayType NativeDisplayType;
|
||||
typedef EGLNativePixmapType NativePixmapType;
|
||||
typedef EGLNativeWindowType NativeWindowType;
|
||||
|
||||
|
||||
/* Define EGLint. This must be a signed integral type large enough to contain
|
||||
* all legal attribute names and values passed into and out of EGL, whether
|
||||
* their type is boolean, bitmask, enumerant (symbolic constant), integer,
|
||||
* handle, or other. While in general a 32-bit integer will suffice, if
|
||||
* handles are 64 bit types, then EGLint should be defined as a signed 64-bit
|
||||
* integer type.
|
||||
*/
|
||||
typedef khronos_int32_t EGLint;
|
||||
|
||||
|
||||
/* C++ / C typecast macros for special EGL handle values */
|
||||
#if defined(__cplusplus)
|
||||
#define EGL_CAST(type, value) (static_cast<type>(value))
|
||||
#else
|
||||
#define EGL_CAST(type, value) ((type) (value))
|
||||
#endif
|
||||
|
||||
#endif /* __eglplatform_h */
|
||||
@@ -17,6 +17,10 @@ elseif(UNIX)
|
||||
list(APPEND libraries PRIVATE ${OPENGL_gl_LIBRARY})
|
||||
endif()
|
||||
|
||||
if(ENABLE_GLES)
|
||||
list(APPEND libraries PRIVATE -lEGL)
|
||||
endif()
|
||||
|
||||
if(ENABLE_XLIB)
|
||||
list(APPEND libraries PRIVATE -lX11)
|
||||
endif()
|
||||
|
||||
@@ -708,6 +708,14 @@ extern "C" void glXWaitX();
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(RENDERDOC_SUPPORT_GLES)
|
||||
|
||||
// symbol defined in libEGL but not in librenderdoc.
|
||||
// Forces link of libEGL.
|
||||
extern "C" int eglWaitGL(void);
|
||||
|
||||
#endif
|
||||
|
||||
void sig_handler(int signo)
|
||||
{
|
||||
if(usingKillSignal)
|
||||
@@ -726,6 +734,14 @@ int main(int argc, char *argv[])
|
||||
if(never_run)
|
||||
glXWaitX();
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(RENDERDOC_SUPPORT_GLES)
|
||||
|
||||
volatile bool never_run = false;
|
||||
if(never_run)
|
||||
eglWaitGL();
|
||||
|
||||
#endif
|
||||
|
||||
signal(SIGINT, sig_handler);
|
||||
@@ -750,6 +766,11 @@ int main(int argc, char *argv[])
|
||||
count++;
|
||||
#endif
|
||||
|
||||
#if defined(RENDERDOC_SUPPORT_GLES)
|
||||
support += "GLES, ";
|
||||
count++;
|
||||
#endif
|
||||
|
||||
if(count == 0)
|
||||
{
|
||||
support += "None.";
|
||||
|
||||
Reference in New Issue
Block a user