X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=retrace%2Fglretrace_cgl.cpp;h=f0d0e2d7d5b29ff4ee0232d479fab8b408374de9;hb=HEAD;hp=63b94b466d6f2804a8663f3effb67f405eeabeb4;hpb=9d27a54b0381610c30964880a5fdd4c27bb6e732;p=apitrace diff --git a/retrace/glretrace_cgl.cpp b/retrace/glretrace_cgl.cpp index 63b94b4..f0d0e2d 100644 --- a/retrace/glretrace_cgl.cpp +++ b/retrace/glretrace_cgl.cpp @@ -31,14 +31,57 @@ #include "glretrace.hpp" +#define kCGLPFAAllRenderers 1 +#define kCGLPFADoubleBuffer 5 +#define kCGLPFAStereo 6 +#define kCGLPFAAuxBuffers 7 +#define kCGLPFAColorSize 8 +#define kCGLPFAAlphaSize 11 +#define kCGLPFADepthSize 12 +#define kCGLPFAStencilSize 13 +#define kCGLPFAAccumSize 14 +#define kCGLPFAMinimumPolicy 51 +#define kCGLPFAMaximumPolicy 52 +#define kCGLPFAOffScreen 53 +#define kCGLPFAFullScreen 54 +#define kCGLPFASampleBuffers 55 +#define kCGLPFASamples 56 +#define kCGLPFAAuxDepthStencil 57 +#define kCGLPFAColorFloat 58 +#define kCGLPFAMultisample 59 +#define kCGLPFASupersample 60 +#define kCGLPFASampleAlpha 61 +#define kCGLPFARendererID 70 +#define kCGLPFASingleRenderer 71 +#define kCGLPFANoRecovery 72 +#define kCGLPFAAccelerated 73 +#define kCGLPFAClosestPolicy 74 +#define kCGLPFARobust 75 +#define kCGLPFABackingStore 76 +#define kCGLPFAMPSafe 78 +#define kCGLPFAWindow 80 +#define kCGLPFAMultiScreen 81 +#define kCGLPFACompliant 83 +#define kCGLPFADisplayMask 84 +#define kCGLPFAPBuffer 90 +#define kCGLPFARemotePBuffer 91 +#define kCGLPFAAllowOfflineRenderers 96 +#define kCGLPFAAcceleratedCompute 97 +#define kCGLPFAOpenGLProfile 99 +#define kCGLPFAVirtualScreenCount 128 + +#define kCGLOGLPVersion_Legacy 0x1000 +#define kCGLOGLPVersion_3_2_Core 0x3200 + + using namespace glretrace; typedef std::map DrawableMap; -typedef std::map ContextMap; +typedef std::map ContextMap; static DrawableMap drawable_map; static ContextMap context_map; -static glws::Context *sharedContext = NULL; +static Context *sharedContext = NULL; static glws::Drawable * @@ -53,14 +96,14 @@ getDrawable(unsigned long drawable_id) { DrawableMap::const_iterator it; it = drawable_map.find(drawable_id); if (it == drawable_map.end()) { - return (drawable_map[drawable_id] = glws::createDrawable(visual[glretrace::defaultProfile])); + return (drawable_map[drawable_id] = glretrace::createDrawable()); } return it->second; } -static glws::Context * +static Context * getContext(unsigned long long ctx) { if (ctx == 0) { return NULL; @@ -69,8 +112,8 @@ getContext(unsigned long long ctx) { ContextMap::const_iterator it; it = context_map.find(ctx); if (it == context_map.end()) { - glws::Context *context; - context_map[ctx] = context = glws::createContext(visual[glretrace::defaultProfile], sharedContext, glretrace::defaultProfile); + Context *context; + context_map[ctx] = context = glretrace::createContext(sharedContext); if (!sharedContext) { sharedContext = context; } @@ -81,45 +124,210 @@ getContext(unsigned long long ctx) { } +static void retrace_CGLChoosePixelFormat(trace::Call &call) { + int profile = kCGLOGLPVersion_Legacy; + + const trace::Array * attribs = dynamic_cast(&call.arg(0)); + if (attribs) { + size_t i = 0; + while (i < attribs->values.size()) { + int param = attribs->values[i++]->toSInt(); + if (param == 0) { + break; + } + + switch (param) { + case kCGLPFAAllRenderers: + case kCGLPFADoubleBuffer: + case kCGLPFAStereo: + case kCGLPFAAuxBuffers: + case kCGLPFAMinimumPolicy: + case kCGLPFAMaximumPolicy: + case kCGLPFAOffScreen: + case kCGLPFAFullScreen: + case kCGLPFAAuxDepthStencil: + case kCGLPFAColorFloat: + case kCGLPFAMultisample: + case kCGLPFASupersample: + case kCGLPFASampleAlpha: + case kCGLPFASingleRenderer: + case kCGLPFANoRecovery: + case kCGLPFAAccelerated: + case kCGLPFAClosestPolicy: + case kCGLPFARobust: + case kCGLPFABackingStore: + case kCGLPFAMPSafe: + case kCGLPFAWindow: + case kCGLPFAMultiScreen: + case kCGLPFACompliant: + case kCGLPFAPBuffer: + case kCGLPFARemotePBuffer: + case kCGLPFAAllowOfflineRenderers: + case kCGLPFAAcceleratedCompute: + break; + + case kCGLPFAColorSize: + case kCGLPFAAlphaSize: + case kCGLPFADepthSize: + case kCGLPFAStencilSize: + case kCGLPFAAccumSize: + case kCGLPFASampleBuffers: + case kCGLPFASamples: + case kCGLPFARendererID: + case kCGLPFADisplayMask: + case kCGLPFAVirtualScreenCount: + ++i; + break; + + case kCGLPFAOpenGLProfile: + profile = attribs->values[i++]->toSInt(); + break; + + default: + retrace::warning(call) << "unexpected attribute " << param << "\n"; + break; + } + } + } + + if (profile == kCGLOGLPVersion_3_2_Core) { + // TODO: Do this on a per visual basis + retrace::coreProfile = true; + } +} + + +static void retrace_CGLCreateContext(trace::Call &call) { + unsigned long long share = call.arg(1).toUIntPtr(); + Context *sharedContext = getContext(share); + + const trace::Array *ctx_ptr = dynamic_cast(&call.arg(2)); + unsigned long long ctx = ctx_ptr->values[0]->toUIntPtr(); + + Context *context = glretrace::createContext(sharedContext); + context_map[ctx] = context; +} + + +static void retrace_CGLDestroyContext(trace::Call &call) { + unsigned long long ctx = call.arg(0).toUIntPtr(); + + ContextMap::iterator it; + it = context_map.find(ctx); + if (it == context_map.end()) { + return; + } + + delete it->second; + + context_map.erase(it); +} + + static void retrace_CGLSetCurrentContext(trace::Call &call) { unsigned long long ctx = call.arg(0).toUIntPtr(); glws::Drawable *new_drawable = getDrawable(ctx); - glws::Context *new_context = getContext(ctx); - - bool result = glws::makeCurrent(new_drawable, new_context); + Context *new_context = getContext(ctx); - if (new_drawable && new_context && result) { - drawable = new_drawable; - context = new_context; - } else { - drawable = NULL; - context = NULL; - } + glretrace::makeCurrent(call, new_drawable, new_context); } static void retrace_CGLFlushDrawable(trace::Call &call) { - if (drawable && context) { - if (double_buffer) { - drawable->swapBuffers(); + unsigned long long ctx = call.arg(0).toUIntPtr(); + Context *context = getContext(ctx); + + if (context) { + if (context->drawable) { + if (retrace::doubleBuffer) { + context->drawable->swapBuffers(); + } else { + glFlush(); + } + frame_complete(call); } else { - glFlush(); + if (retrace::debug) { + retrace::warning(call) << "context has no drawable\n"; + } + } + } +} + + +/** + * We can't fully reimplement CGLTexImageIOSurface2D, as external IOSurface are + * no longer present. Simply emit a glTexImage2D to ensure the texture storage + * is present. + * + * See also: + * - /System/Library/Frameworks/OpenGL.framework/Headers/CGLIOSurface.h + */ +static void retrace_CGLTexImageIOSurface2D(trace::Call &call) { + if (retrace::debug) { + retrace::warning(call) << "external IOSurface not supported\n"; + } + + unsigned long long ctx = call.arg(0).toUIntPtr(); + Context *context = getContext(ctx); + + GLenum target; + target = static_cast((call.arg(1)).toSInt()); + + GLint level = 0; + + GLint internalformat; + internalformat = static_cast((call.arg(2)).toSInt()); + + GLsizei width; + width = (call.arg(3)).toSInt(); + + GLsizei height; + height = (call.arg(4)).toSInt(); + + GLint border = 0; + + GLenum format; + format = static_cast((call.arg(5)).toSInt()); + + GLenum type; + type = static_cast((call.arg(6)).toSInt()); + + GLvoid * pixels = NULL; + + if (glretrace::getCurrentContext() != context) { + if (retrace::debug) { + retrace::warning(call) << "current context mismatch\n"; } + } + + glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); - frame_complete(call); + if (retrace::debug && !glretrace::insideGlBeginEnd) { + glretrace::checkGlError(call); } } const retrace::Entry glretrace::cgl_callbacks[] = { - {"CGLSetCurrentContext", &retrace_CGLSetCurrentContext}, - {"CGLGetCurrentContext", &retrace::ignore}, - {"CGLEnable", &retrace::ignore}, + {"CGLChoosePixelFormat", &retrace_CGLChoosePixelFormat}, + {"CGLCreateContext", &retrace_CGLCreateContext}, + {"CGLDestroyContext", &retrace_CGLDestroyContext}, + {"CGLDestroyPixelFormat", &retrace::ignore}, {"CGLDisable", &retrace::ignore}, - {"CGLSetParameter", &retrace::ignore}, - {"CGLGetParameter", &retrace::ignore}, + {"CGLEnable", &retrace::ignore}, + {"CGLErrorString", &retrace::ignore}, {"CGLFlushDrawable", &retrace_CGLFlushDrawable}, + {"CGLGetCurrentContext", &retrace::ignore}, + {"CGLGetOption", &retrace::ignore}, + {"CGLGetParameter", &retrace::ignore}, + {"CGLGetVersion", &retrace::ignore}, + {"CGLGetVirtualScreen", &retrace::ignore}, + {"CGLIsEnabled", &retrace::ignore}, + {"CGLSetCurrentContext", &retrace_CGLSetCurrentContext}, + {"CGLSetParameter", &retrace::ignore}, + {"CGLTexImageIOSurface2D", &retrace_CGLTexImageIOSurface2D}, + {"CGLUpdateContext", &retrace::ignore}, {NULL, NULL}, };