mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-09 09:10:49 +00:00
e074c3aba0
Changed some naming of parameters in the NSGL Objective-C functions
275 lines
8.3 KiB
C++
275 lines
8.3 KiB
C++
/******************************************************************************
|
|
* The MIT License (MIT)
|
|
*
|
|
* Copyright (c) 2019-2021 Baldur Karlsson
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* 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 Software.
|
|
*
|
|
* THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
******************************************************************************/
|
|
|
|
#define GL_GLEXT_PROTOTYPES
|
|
|
|
#include "cgl_dispatch_table.h"
|
|
#include "gl_common.h"
|
|
|
|
#include "apple_gl_hook_defs.h"
|
|
|
|
// helpers defined in cgl_platform.mm
|
|
extern "C" int NSGL_getLayerWidth(void *layer);
|
|
extern "C" int NSGL_getLayerHeight(void *layer);
|
|
extern "C" void *NSGL_createContext(void *view, void *shareContext);
|
|
extern "C" void NSGL_makeCurrentContext(void *context);
|
|
extern "C" void NSGL_update(void *context);
|
|
extern "C" void NSGL_flushBuffer(void *context);
|
|
extern "C" void NSGL_destroyContext(void *context);
|
|
|
|
// helper for cgl_platform.mm
|
|
extern "C" void NSGL_LogText(const char *text)
|
|
{
|
|
RDCLOG("CGL: %s", text);
|
|
}
|
|
|
|
// gl functions (used for quad rendering on legacy contexts)
|
|
extern "C" void glPushMatrix();
|
|
extern "C" void glLoadIdentity();
|
|
extern "C" void glMatrixMode(GLenum);
|
|
extern "C" void glOrtho(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble);
|
|
extern "C" void glPopMatrix();
|
|
extern "C" void glBegin(GLenum);
|
|
extern "C" void glVertex2f(float, float);
|
|
extern "C" void glTexCoord2f(float, float);
|
|
extern "C" void glEnd();
|
|
|
|
#define QUAD_GL_FUNCS(FUNC) \
|
|
FUNC(glGetIntegerv); \
|
|
FUNC(glPushMatrix); \
|
|
FUNC(glLoadIdentity); \
|
|
FUNC(glMatrixMode); \
|
|
FUNC(glOrtho); \
|
|
FUNC(glPopMatrix); \
|
|
FUNC(glBegin); \
|
|
FUNC(glVertex2f); \
|
|
FUNC(glTexCoord2f); \
|
|
FUNC(glEnd);
|
|
|
|
#define DECL_PTR(a) decltype(&a) a;
|
|
struct QuadGL
|
|
{
|
|
QUAD_GL_FUNCS(DECL_PTR);
|
|
};
|
|
|
|
template <>
|
|
rdcstr DoStringise(const CGLError &el)
|
|
{
|
|
BEGIN_ENUM_STRINGISE(CGLError);
|
|
{
|
|
STRINGISE_ENUM_NAMED(kCGLNoError, "no error");
|
|
STRINGISE_ENUM_NAMED(kCGLBadAttribute, "invalid pixel format attribute");
|
|
STRINGISE_ENUM_NAMED(kCGLBadProperty, "invalid renderer property");
|
|
STRINGISE_ENUM_NAMED(kCGLBadPixelFormat, "invalid pixel format");
|
|
STRINGISE_ENUM_NAMED(kCGLBadRendererInfo, "invalid renderer info");
|
|
STRINGISE_ENUM_NAMED(kCGLBadContext, "invalid context");
|
|
STRINGISE_ENUM_NAMED(kCGLBadDrawable, "invalid drawable");
|
|
STRINGISE_ENUM_NAMED(kCGLBadDisplay, "invalid graphics device");
|
|
STRINGISE_ENUM_NAMED(kCGLBadState, "invalid context state");
|
|
STRINGISE_ENUM_NAMED(kCGLBadValue, "invalid numerical value");
|
|
STRINGISE_ENUM_NAMED(kCGLBadMatch, "invalid share context");
|
|
STRINGISE_ENUM_NAMED(kCGLBadEnumeration, "invalid enumerant");
|
|
STRINGISE_ENUM_NAMED(kCGLBadOffScreen, "invalid offscreen drawable");
|
|
STRINGISE_ENUM_NAMED(kCGLBadFullScreen, "invalid fullscreen drawable");
|
|
STRINGISE_ENUM_NAMED(kCGLBadWindow, "invalid window");
|
|
STRINGISE_ENUM_NAMED(kCGLBadAddress, "invalid pointer");
|
|
STRINGISE_ENUM_NAMED(kCGLBadCodeModule, "invalid code module");
|
|
STRINGISE_ENUM_NAMED(kCGLBadAlloc, "invalid memory allocation");
|
|
STRINGISE_ENUM_NAMED(kCGLBadConnection, "invalid CoreGraphics connection");
|
|
}
|
|
END_ENUM_STRINGISE();
|
|
}
|
|
|
|
class CGLPlatform : public GLPlatform
|
|
{
|
|
bool MakeContextCurrent(GLWindowingData data)
|
|
{
|
|
if(RenderDoc::Inst().IsReplayApp())
|
|
{
|
|
NSGL_makeCurrentContext(data.nsgl_ctx);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if(CGL.CGLSetCurrentContext)
|
|
{
|
|
CGLError err = CGL.CGLSetCurrentContext(data.ctx);
|
|
if(err == kCGLNoError)
|
|
return true;
|
|
RDCERR("MakeContextCurrent: %s", ToStr(err).c_str());
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
GLWindowingData CloneTemporaryContext(GLWindowingData share)
|
|
{
|
|
GLWindowingData ret = share;
|
|
|
|
ret.ctx = NULL;
|
|
|
|
if(RenderDoc::Inst().IsReplayApp())
|
|
{
|
|
RDCASSERT(share.nsgl_ctx);
|
|
ret.nsgl_ctx = NSGL_createContext(NULL, share.nsgl_ctx);
|
|
}
|
|
else
|
|
{
|
|
if(share.ctx && CGL.CGLCreateContext)
|
|
{
|
|
CGLError err = CGL.CGLCreateContext(share.pix, share.ctx, &ret.ctx);
|
|
RDCASSERTMSG("Error creating temporary context", err == kCGLNoError, err);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void DeleteClonedContext(GLWindowingData context)
|
|
{
|
|
if(RenderDoc::Inst().IsReplayApp())
|
|
{
|
|
NSGL_destroyContext(context.nsgl_ctx);
|
|
}
|
|
else
|
|
{
|
|
if(context.ctx && CGL.CGLDestroyContext)
|
|
CGL.CGLDestroyContext(context.ctx);
|
|
}
|
|
}
|
|
void DeleteReplayContext(GLWindowingData context)
|
|
{
|
|
RDCASSERT(context.nsgl_ctx);
|
|
NSGL_destroyContext(context.nsgl_ctx);
|
|
}
|
|
void SwapBuffers(GLWindowingData context) { NSGL_flushBuffer(context.nsgl_ctx); }
|
|
void WindowResized(GLWindowingData context) { NSGL_update(context.nsgl_ctx); }
|
|
void GetOutputWindowDimensions(GLWindowingData context, int32_t &w, int32_t &h)
|
|
{
|
|
if(context.layer)
|
|
{
|
|
w = NSGL_getLayerWidth(context.layer);
|
|
h = NSGL_getLayerHeight(context.layer);
|
|
}
|
|
else
|
|
{
|
|
w = h = 0;
|
|
}
|
|
}
|
|
bool IsOutputWindowVisible(GLWindowingData context) { return true; }
|
|
void *GetReplayFunction(const char *funcname)
|
|
{
|
|
#undef APPLE_FUNC
|
|
#define APPLE_FUNC(function) \
|
|
if(!strcmp(funcname, STRINGIZE(function))) \
|
|
return (void *)&::function;
|
|
|
|
ForEachAppleSupported();
|
|
|
|
return NULL;
|
|
}
|
|
bool CanCreateGLContext() { return true; }
|
|
bool CanCreateGLESContext() { return false; }
|
|
bool PopulateForReplay() { return CGL.PopulateForReplay(); }
|
|
GLWindowingData MakeOutputWindow(WindowingData window, bool depth, GLWindowingData share_context)
|
|
{
|
|
GLWindowingData ret = {};
|
|
|
|
if(window.system == WindowingSystem::MacOS)
|
|
{
|
|
RDCASSERT(window.macOS.layer && window.macOS.view);
|
|
|
|
ret.nsgl_ctx = NSGL_createContext(window.macOS.view, share_context.nsgl_ctx);
|
|
ret.wnd = window.macOS.view;
|
|
ret.layer = window.macOS.layer;
|
|
|
|
return ret;
|
|
}
|
|
else if(window.system == WindowingSystem::Unknown || window.system == WindowingSystem::Headless)
|
|
{
|
|
ret.nsgl_ctx = NSGL_createContext(NULL, share_context.nsgl_ctx);
|
|
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
RDCERR("Unexpected window system %u", system);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
ReplayStatus InitialiseAPI(GLWindowingData &replayContext, RDCDriver api, bool debug)
|
|
{
|
|
RDCASSERT(api == RDCDriver::OpenGL);
|
|
|
|
replayContext.nsgl_ctx = NSGL_createContext(NULL, NULL);
|
|
|
|
return ReplayStatus::Succeeded;
|
|
}
|
|
|
|
void DrawQuads(float width, float height, const rdcarray<Vec4f> &vertices)
|
|
{
|
|
static QuadGL quadGL = {};
|
|
|
|
if(!quadGL.glBegin)
|
|
{
|
|
#define FETCH_PTR(a) quadGL.a = &::a;
|
|
QUAD_GL_FUNCS(FETCH_PTR)
|
|
}
|
|
::DrawQuads(quadGL, width, height, vertices);
|
|
}
|
|
} cglPlatform;
|
|
|
|
CGLDispatchTable CGL = {};
|
|
|
|
GLPlatform &GetGLPlatform()
|
|
{
|
|
return cglPlatform;
|
|
}
|
|
|
|
bool CGLDispatchTable::PopulateForReplay()
|
|
{
|
|
RDCASSERT(RenderDoc::Inst().IsReplayApp());
|
|
|
|
RDCDEBUG("Initialising GL function pointers");
|
|
|
|
bool symbols_ok = true;
|
|
|
|
#define LOAD_FUNC(func) \
|
|
if(!this->func) \
|
|
this->func = &::func; \
|
|
\
|
|
if(!this->func) \
|
|
{ \
|
|
symbols_ok = false; \
|
|
RDCWARN("Unable to load '%s'", STRINGIZE(func)); \
|
|
}
|
|
|
|
CGL_HOOKED_SYMBOLS(LOAD_FUNC)
|
|
CGL_NONHOOKED_SYMBOLS(LOAD_FUNC)
|
|
|
|
#undef LOAD_FUNC
|
|
return symbols_ok;
|
|
}
|