diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2022-09-29 16:25:14 +0200 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2022-09-29 16:25:14 +0200 |
| commit | c96a4f3141259d412b249144086492ec4c400355 (patch) | |
| tree | 5aeffc28022dd6708e792ac88e3331d778795df0 /src/drivers/Cocoa | |
| parent | 694eaef99c25c4f94c4f2d5ffe6598bcca6674fc (diff) | |
macOS platform: rename Fl_Cocoa_Gl_Window_Driver.cxx to .mm
Diffstat (limited to 'src/drivers/Cocoa')
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H | 1 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm (renamed from src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx) | 208 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H | 15 |
3 files changed, 173 insertions, 51 deletions
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H index f0456eec9..01ab231c2 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H +++ b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H @@ -28,7 +28,6 @@ class Fl_Gl_Choice; class Fl_Cocoa_Gl_Window_Driver : public Fl_Gl_Window_Driver { NSOpenGLContext *gl1ctxt; // GL1 context in addition to GL3 context - static void delayed_addgl1ctxt(void *data); friend Fl_Gl_Window_Driver* Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *); Fl_Cocoa_Gl_Window_Driver(Fl_Gl_Window *win); virtual float pixels_per_unit(); diff --git a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm index 3ee281b37..741ab3373 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx +++ b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm @@ -27,13 +27,7 @@ #include <FL/Fl_Image_Surface.H> #include <dlfcn.h> - -#ifdef __OBJC__ -@class NSOpenGLPixelFormat; -#else -class NSOpenGLPixelFormat; -#endif // __OBJC__ - +#import <Cocoa/Cocoa.h> // Describes crap needed to create a GLContext. class Fl_Cocoa_Gl_Choice : public Fl_Gl_Choice { @@ -52,12 +46,102 @@ Fl_Cocoa_Gl_Window_Driver::Fl_Cocoa_Gl_Window_Driver(Fl_Gl_Window *win) : gl1ctxt = NULL; } + +static NSOpenGLPixelFormat* mode_to_NSOpenGLPixelFormat(int m, const int *alistp) +{ + NSOpenGLPixelFormatAttribute attribs[32]; + int n = 0; + // AGL-style code remains commented out for comparison + if (!alistp) { + if (m & FL_INDEX) { + //list[n++] = AGL_BUFFER_SIZE; list[n++] = 8; + } else { + //list[n++] = AGL_RGBA; + //list[n++] = AGL_GREEN_SIZE; + //list[n++] = (m & FL_RGB8) ? 8 : 1; + attribs[n++] = NSOpenGLPFAColorSize; + attribs[n++] = (NSOpenGLPixelFormatAttribute)((m & FL_RGB8) ? 32 : 1); + if (m & FL_ALPHA) { + //list[n++] = AGL_ALPHA_SIZE; + attribs[n++] = NSOpenGLPFAAlphaSize; + attribs[n++] = (NSOpenGLPixelFormatAttribute)((m & FL_RGB8) ? 8 : 1); + } + if (m & FL_ACCUM) { + //list[n++] = AGL_ACCUM_GREEN_SIZE; list[n++] = 1; + attribs[n++] = NSOpenGLPFAAccumSize; + attribs[n++] = (NSOpenGLPixelFormatAttribute)1; + if (m & FL_ALPHA) { + //list[n++] = AGL_ACCUM_ALPHA_SIZE; list[n++] = 1; + } + } + } + if (m & FL_DOUBLE) { + //list[n++] = AGL_DOUBLEBUFFER; + attribs[n++] = NSOpenGLPFADoubleBuffer; + } + if (m & FL_DEPTH) { + //list[n++] = AGL_DEPTH_SIZE; list[n++] = 24; + attribs[n++] = NSOpenGLPFADepthSize; + attribs[n++] = (NSOpenGLPixelFormatAttribute)24; + } + if (m & FL_STENCIL) { + //list[n++] = AGL_STENCIL_SIZE; list[n++] = 1; + attribs[n++] = NSOpenGLPFAStencilSize; + attribs[n++] = (NSOpenGLPixelFormatAttribute)1; + } + if (m & FL_STEREO) { + //list[n++] = AGL_STEREO; + attribs[n++] = NSOpenGLPFAStereo; + } + if ((m & FL_MULTISAMPLE) && fl_mac_os_version >= 100400) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + attribs[n++] = NSOpenGLPFAMultisample, // 10.4 +#endif + attribs[n++] = NSOpenGLPFASampleBuffers; attribs[n++] = (NSOpenGLPixelFormatAttribute)1; + attribs[n++] = NSOpenGLPFASamples; attribs[n++] = (NSOpenGLPixelFormatAttribute)4; + } +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 +#define NSOpenGLPFAOpenGLProfile (NSOpenGLPixelFormatAttribute)99 +#define kCGLPFAOpenGLProfile NSOpenGLPFAOpenGLProfile +#define NSOpenGLProfileVersionLegacy (NSOpenGLPixelFormatAttribute)0x1000 +#define NSOpenGLProfileVersion3_2Core (NSOpenGLPixelFormatAttribute)0x3200 +#define kCGLOGLPVersion_Legacy NSOpenGLProfileVersionLegacy +#endif + if (fl_mac_os_version >= 100700) { + attribs[n++] = NSOpenGLPFAOpenGLProfile; + attribs[n++] = (m & FL_OPENGL3) ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy; + } + } else { + while (alistp[n] && n < 30) { + if (alistp[n] == kCGLPFAOpenGLProfile) { + if (fl_mac_os_version < 100700) { + if (alistp[n+1] != kCGLOGLPVersion_Legacy) return nil; + n += 2; + continue; + } + } + attribs[n] = (NSOpenGLPixelFormatAttribute)alistp[n]; + n++; + } + } + attribs[n] = (NSOpenGLPixelFormatAttribute)0; + NSOpenGLPixelFormat *pixform = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; + /*GLint color,alpha,accum,depth; + [pixform getValues:&color forAttribute:NSOpenGLPFAColorSize forVirtualScreen:0]; + [pixform getValues:&alpha forAttribute:NSOpenGLPFAAlphaSize forVirtualScreen:0]; + [pixform getValues:&accum forAttribute:NSOpenGLPFAAccumSize forVirtualScreen:0]; + [pixform getValues:&depth forAttribute:NSOpenGLPFADepthSize forVirtualScreen:0]; + NSLog(@"color=%d alpha=%d accum=%d depth=%d",color,alpha,accum,depth);*/ + return pixform; +} + + Fl_Gl_Choice *Fl_Cocoa_Gl_Window_Driver::find(int m, const int *alistp) { Fl::screen_driver()->open_display(); // useful when called through gl_start() Fl_Cocoa_Gl_Choice *g = (Fl_Cocoa_Gl_Choice*)Fl_Gl_Window_Driver::find_begin(m, alistp); if (g) return g; - NSOpenGLPixelFormat* fmt = Fl_Cocoa_Window_Driver::mode_to_NSOpenGLPixelFormat(m, alistp); + NSOpenGLPixelFormat* fmt = mode_to_NSOpenGLPixelFormat(m, alistp); if (!fmt) return 0; g = new Fl_Cocoa_Gl_Choice(m, alistp, first); first = g; @@ -65,16 +149,53 @@ Fl_Gl_Choice *Fl_Cocoa_Gl_Window_Driver::find(int m, const int *alistp) return g; } + +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_VERSION_12_0 +# define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity +#endif + +static void remove_gl_context_opacity(NSOpenGLContext *ctx) { + GLint gl_opacity; + [ctx getValues:&gl_opacity forParameter:NSOpenGLContextParameterSurfaceOpacity]; + if (gl_opacity != 0) { + gl_opacity = 0; + [ctx setValues:&gl_opacity forParameter:NSOpenGLContextParameterSurfaceOpacity]; + } +} + + +static NSOpenGLContext *create_GLcontext_for_window( + NSOpenGLPixelFormat *pixelformat, + NSOpenGLContext *shared_ctx, Fl_Window *window) +{ + NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixelformat shareContext:shared_ctx]; + if (shared_ctx && !context) context = [[NSOpenGLContext alloc] initWithFormat:pixelformat shareContext:nil]; + if (context) { + NSView *view = [fl_xid(window) contentView]; + if (fl_mac_os_version >= 100700) { + //replaces [view setWantsBestResolutionOpenGLSurface:YES] without compiler warning + typedef void (*bestResolutionIMP)(id, SEL, BOOL); + static bestResolutionIMP addr = (bestResolutionIMP)[NSView instanceMethodForSelector:@selector(setWantsBestResolutionOpenGLSurface:)]; + addr(view, @selector(setWantsBestResolutionOpenGLSurface:), Fl::use_high_res_GL() != 0); + } + [context setView:view]; + if (Fl_Cocoa_Window_Driver::driver(window)->subRect()) { + remove_gl_context_opacity(context); + } + } + return context; +} + GLContext Fl_Cocoa_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) { GLContext context, shared_ctx = 0; if (context_list && nContext) shared_ctx = context_list[0]; // resets the pile of string textures used to draw strings // necessary before the first context is created if (!shared_ctx) gl_texture_reset(); - context = Fl_Cocoa_Window_Driver::create_GLcontext_for_window(((Fl_Cocoa_Gl_Choice*)g)->pixelformat, (NSOpenGLContext*)shared_ctx, window); + context = create_GLcontext_for_window(((Fl_Cocoa_Gl_Choice*)g)->pixelformat, (NSOpenGLContext*)shared_ctx, window); if (!context) return 0; add_context(context); - Fl_Cocoa_Window_Driver::GLcontext_makecurrent((NSOpenGLContext*)context); + [(NSOpenGLContext*)context makeCurrentContext]; glClearColor(0., 0., 0., 1.); apply_scissor(); return (context); @@ -84,7 +205,7 @@ void Fl_Cocoa_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) if (context != cached_context || w != cached_window) { cached_context = context; cached_window = w; - Fl_Cocoa_Window_Driver::GLcontext_makecurrent((NSOpenGLContext*)context); + [(NSOpenGLContext*)context makeCurrentContext]; } } @@ -92,9 +213,9 @@ void Fl_Cocoa_Gl_Window_Driver::delete_gl_context(GLContext context) { if (cached_context == context) { cached_context = 0; cached_window = 0; - Fl_Cocoa_Window_Driver::GL_cleardrawable(); + [[NSOpenGLContext currentContext] clearDrawable]; } - Fl_Cocoa_Window_Driver::GLcontext_release((NSOpenGLContext*)context); + [(NSOpenGLContext*)context release]; del_context(context); } @@ -151,7 +272,7 @@ void Fl_Cocoa_Gl_Window_Driver::make_current_before() { if (d->changed_resolution()){ d->changed_resolution(false); pWindow->invalidate(); - Fl_Cocoa_Window_Driver::GLcontext_update((NSOpenGLContext*)pWindow->context()); + [(NSOpenGLContext*)pWindow->context() update]; } } @@ -185,9 +306,9 @@ void Fl_Cocoa_Gl_Window_Driver::swap_buffers() { glPopMatrix(); glMatrixMode(matrixmode); glRasterPos3f(pos[0], pos[1], pos[2]); // restore original glRasterPos + } else { + [(NSOpenGLContext*)pWindow->context() flushBuffer]; } - else - Fl_Cocoa_Window_Driver::flush_context((NSOpenGLContext*)pWindow->context());//aglSwapBuffers((AGLContext)context_); } char Fl_Cocoa_Gl_Window_Driver::swap_type() {return copy;} @@ -198,10 +319,10 @@ static void delayed_redraw(Fl_Gl_Window *win) { void Fl_Cocoa_Gl_Window_Driver::resize(int is_a_resize, int w, int h) { if (pWindow->shown()) apply_scissor(); - Fl_Cocoa_Window_Driver::GLcontext_update((NSOpenGLContext*)pWindow->context()); + [(NSOpenGLContext*)pWindow->context() update]; if (gl1ctxt) { - Fl_Cocoa_Window_Driver::gl1ctxt_resize(gl1ctxt); - Fl_Cocoa_Window_Driver::GLcontext_update(gl1ctxt); + [[gl1ctxt view] setFrame:[[[gl1ctxt view] superview] frame]]; + [gl1ctxt update]; Fl::add_timeout(0.01, (Fl_Timeout_Handler)delayed_redraw, pWindow); } } @@ -209,7 +330,7 @@ void Fl_Cocoa_Gl_Window_Driver::resize(int is_a_resize, int w, int h) { void Fl_Cocoa_Gl_Window_Driver::apply_scissor() { CGRect *extents = Fl_Cocoa_Window_Driver::driver(pWindow)->subRect(); if (extents) { - Fl_Cocoa_Window_Driver::remove_gl_context_opacity((NSOpenGLContext*)pWindow->context()); + remove_gl_context_opacity((NSOpenGLContext*)pWindow->context()); glDisable(GL_SCISSOR_TEST); GLdouble vals[4]; glGetDoublev(GL_COLOR_CLEAR_VALUE, vals); @@ -251,7 +372,7 @@ char *Fl_Cocoa_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, i } void Fl_Cocoa_Gl_Window_Driver::gl_start() { - Fl_Cocoa_Window_Driver::gl_start((NSOpenGLContext*)gl_start_context); + [(NSOpenGLContext*)gl_start_context update]; } // convert BGRA to RGB and also exchange top and bottom @@ -283,8 +404,9 @@ Fl_RGB_Image* Fl_Cocoa_Gl_Window_Driver::capture_gl_rectangle(int x, int y, int if (factor != 1) { w *= factor; h *= factor; x *= factor; y *= factor; } - Fl_Cocoa_Window_Driver::GLcontext_makecurrent((NSOpenGLContext*)glw->context()); - Fl_Cocoa_Window_Driver::flush_context((NSOpenGLContext*)glw->context()); // to capture also the overlay and for directGL demo + [(NSOpenGLContext*)glw->context() makeCurrentContext]; +// to capture also the overlay and for directGL demo + [(NSOpenGLContext*)glw->context() flushBuffer]; // Read OpenGL context pixels directly. // For extra safety, save & restore OpenGL states that are changed glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); @@ -302,7 +424,7 @@ Fl_RGB_Image* Fl_Cocoa_Gl_Window_Driver::capture_gl_rectangle(int x, int y, int baseAddress = convert_BGRA_to_RGB(baseAddress, w, h, mByteWidth); Fl_RGB_Image *img = new Fl_RGB_Image(baseAddress, w, h, 3, 3 * w); img->alloc_array = 1; - Fl_Cocoa_Window_Driver::flush_context((NSOpenGLContext*)glw->context()); + [(NSOpenGLContext*)glw->context() flushBuffer]; return img; } @@ -332,35 +454,51 @@ static struct win_view { NSOpenGLContext *gl1ctxt; } win_view_struct; -void Fl_Cocoa_Gl_Window_Driver::delayed_addgl1ctxt(void *d) { - struct win_view *data = (struct win_view *)d; - Fl_Cocoa_Window_Driver::driver(data->win)->gl1ctxt_add(data->gl1ctxt, data->gl1view); + +static void delayed_addgl1ctxt(struct win_view *data) { + NSView *flview = [fl_mac_xid(data->win) contentView]; + [flview addSubview:data->gl1view]; + [data->gl1view release]; +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_7 + if (fl_mac_os_version >= 100700 && Fl::use_high_res_GL()) { + [data->gl1view setWantsBestResolutionOpenGLSurface:YES]; + } +#endif + [data->gl1ctxt setView:data->gl1view]; + remove_gl_context_opacity(data->gl1ctxt); data->win->redraw(); } + void Fl_Cocoa_Gl_Window_Driver::switch_to_GL1() { if (!gl1ctxt) { - gl1ctxt = Fl_Cocoa_Window_Driver::driver(pWindow)->gl1ctxt_create( - &win_view_struct.gl1view); + NSView *view = [fl_xid(pWindow) contentView]; + win_view_struct.gl1view = [[NSView alloc] initWithFrame:[view frame]]; + NSOpenGLPixelFormat *gl1pixelformat = mode_to_NSOpenGLPixelFormat( + FL_RGB8 | FL_ALPHA | FL_SINGLE, NULL); + gl1ctxt = [[NSOpenGLContext alloc] + initWithFormat:gl1pixelformat shareContext:nil]; + [gl1pixelformat release]; win_view_struct.win = pWindow; win_view_struct.gl1ctxt = gl1ctxt; - Fl::add_timeout(0.01, - Fl_Cocoa_Gl_Window_Driver::delayed_addgl1ctxt, - &win_view_struct); + Fl::add_timeout(0.01, (Fl_Timeout_Handler)delayed_addgl1ctxt, + &win_view_struct); } - Fl_Cocoa_Window_Driver::GLcontext_makecurrent(gl1ctxt); + [gl1ctxt makeCurrentContext]; glClearColor(0., 0., 0., 0.); glClear(GL_COLOR_BUFFER_BIT); } + void Fl_Cocoa_Gl_Window_Driver::switch_back() { glFlush(); - Fl_Cocoa_Window_Driver::GLcontext_makecurrent((NSOpenGLContext*)pWindow->context()); + [(NSOpenGLContext*)pWindow->context() makeCurrentContext]; } + void Fl_Cocoa_Gl_Window_Driver::gl_hide_before(void *&) { if (gl1ctxt) { - Fl_Cocoa_Window_Driver::GLcontext_release(gl1ctxt); + [gl1ctxt release]; gl1ctxt = 0; } } diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H index 16cea4e67..520c4c239 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H +++ b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H @@ -146,21 +146,6 @@ public: void draw_titlebar_to_context(CGContextRef gc, int w, int h); virtual int scroll(int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, void (*draw_area)(void*, int,int,int,int), void* data); - // these functions are OpenGL-related and use objective-c - // they are put here to avoid libfltk_gl dependency in Fl_cocoa.mm - static NSOpenGLContext* create_GLcontext_for_window(NSOpenGLPixelFormat *pixelformat, NSOpenGLContext *shared_ctx, Fl_Window *window); - static NSOpenGLPixelFormat *mode_to_NSOpenGLPixelFormat(int mode, const int*); // uses Objective-c - static void GLcontext_update(NSOpenGLContext*); // uses Objective-c - static void GLcontext_release(NSOpenGLContext*); // uses Objective-c - static void flush_context(NSOpenGLContext*); // uses Objective-c - static void GLcontext_makecurrent(NSOpenGLContext*); // uses Objective-c - static void GL_cleardrawable(void); // uses Objective-c - static void gl_start(NSOpenGLContext*); // uses Objective-c - static void remove_gl_context_opacity(NSOpenGLContext*); // uses Objective-c - NSOpenGLContext *gl1ctxt_create(NSView **); // uses Objective-c - void gl1ctxt_add(NSOpenGLContext*, NSView*); // uses Objective-c - static void gl1ctxt_resize(NSOpenGLContext*); // uses Objective-c - //icons virtual void icons(const Fl_RGB_Image *icons[], int count); NSImage *icon_image; |
