Browse Source

cocoa: Split out GL-specific code into new cocoagldisplay module

This makes it possible to create subclasses for tinydisplay and vulkandisplay without having to duplicate code
rdb 2 years ago
parent
commit
545ede9d94
31 changed files with 990 additions and 508 deletions
  1. 13 2
      makepanda/makepanda.py
  2. 1 0
      panda/CMakeLists.txt
  3. 3 3
      panda/metalibs/pandagl/CMakeLists.txt
  4. 7 7
      panda/metalibs/pandagl/pandagl.cxx
  5. 3 7
      panda/src/cocoadisplay/CMakeLists.txt
  6. 1 28
      panda/src/cocoadisplay/cocoaGraphicsPipe.h
  7. 1 120
      panda/src/cocoadisplay/cocoaGraphicsPipe.mm
  8. 15 6
      panda/src/cocoadisplay/cocoaGraphicsWindow.h
  9. 26 244
      panda/src/cocoadisplay/cocoaGraphicsWindow.mm
  10. 154 0
      panda/src/cocoadisplay/cocoaGraphicsWindow.mm.rej
  11. 1 4
      panda/src/cocoadisplay/cocoaPandaView.h
  12. 4 14
      panda/src/cocoadisplay/cocoaPandaView.mm
  13. 0 12
      panda/src/cocoadisplay/config_cocoadisplay.mm
  14. 1 3
      panda/src/cocoadisplay/p3cocoadisplay_composite1.mm
  15. 28 0
      panda/src/cocoagldisplay/CMakeLists.txt
  16. 1 1
      panda/src/cocoagldisplay/cocoaGLGraphicsBuffer.I
  17. 11 11
      panda/src/cocoagldisplay/cocoaGLGraphicsBuffer.h
  18. 17 17
      panda/src/cocoagldisplay/cocoaGLGraphicsBuffer.mm
  19. 12 0
      panda/src/cocoagldisplay/cocoaGLGraphicsPipe.I
  20. 65 0
      panda/src/cocoagldisplay/cocoaGLGraphicsPipe.h
  21. 150 0
      panda/src/cocoagldisplay/cocoaGLGraphicsPipe.mm
  22. 4 4
      panda/src/cocoagldisplay/cocoaGLGraphicsStateGuardian.I
  23. 9 9
      panda/src/cocoagldisplay/cocoaGLGraphicsStateGuardian.h
  24. 16 16
      panda/src/cocoagldisplay/cocoaGLGraphicsStateGuardian.mm
  25. 12 0
      panda/src/cocoagldisplay/cocoaGLGraphicsWindow.I
  26. 66 0
      panda/src/cocoagldisplay/cocoaGLGraphicsWindow.h
  27. 274 0
      panda/src/cocoagldisplay/cocoaGLGraphicsWindow.mm
  28. 21 0
      panda/src/cocoagldisplay/config_cocoagldisplay.h
  29. 60 0
      panda/src/cocoagldisplay/config_cocoagldisplay.mm
  30. 5 0
      panda/src/cocoagldisplay/p3cocoagldisplay_composite1.mm
  31. 9 0
      panda/src/pandabase/pandasymbols.h

+ 13 - 2
makepanda/makepanda.py

@@ -3288,6 +3288,8 @@ if GetTarget() == 'windows':
     CopyAllHeaders('panda/src/wgldisplay')
     CopyAllHeaders('panda/src/wgldisplay')
 elif GetTarget() == 'darwin':
 elif GetTarget() == 'darwin':
     CopyAllHeaders('panda/src/cocoadisplay')
     CopyAllHeaders('panda/src/cocoadisplay')
+    if not PkgSkip('GL'):
+        CopyAllHeaders('panda/src/cocoagldisplay')
 elif GetTarget() == 'android':
 elif GetTarget() == 'android':
     CopyAllHeaders('panda/src/android')
     CopyAllHeaders('panda/src/android')
     CopyAllHeaders('panda/src/androiddisplay')
     CopyAllHeaders('panda/src/androiddisplay')
@@ -4647,15 +4649,24 @@ if GetTarget() not in ['windows', 'darwin'] and not PkgSkip("GL") and not PkgSki
 # DIRECTORY: panda/src/cocoadisplay/
 # DIRECTORY: panda/src/cocoadisplay/
 #
 #
 
 
-if GetTarget() == 'darwin' and PkgSkip("COCOA")==0 and not PkgSkip("GL"):
-    OPTS=['DIR:panda/src/cocoadisplay', 'BUILDING:PANDAGL', 'GL', 'NVIDIACG', 'CGGL']
+if GetTarget() == 'darwin' and not PkgSkip("COCOA"):
+    OPTS=['DIR:panda/src/cocoadisplay', 'BUILDING:PANDAGL', 'COCOA']
     TargetAdd('p3cocoadisplay_composite1.obj', opts=OPTS, input='p3cocoadisplay_composite1.mm')
     TargetAdd('p3cocoadisplay_composite1.obj', opts=OPTS, input='p3cocoadisplay_composite1.mm')
+
+#
+# DIRECTORY: panda/src/cocoagldisplay/
+#
+
+if GetTarget() == 'darwin' and not PkgSkip("COCOA") and not PkgSkip("GL"):
+    OPTS=['DIR:panda/src/cocoagldisplay', 'BUILDING:PANDAGL', 'GL', 'NVIDIACG', 'CGGL']
+    TargetAdd('p3cocoagldisplay_composite1.obj', opts=OPTS, input='p3cocoagldisplay_composite1.mm')
     OPTS=['DIR:panda/metalibs/pandagl', 'BUILDING:PANDAGL', 'GL', 'NVIDIACG', 'CGGL']
     OPTS=['DIR:panda/metalibs/pandagl', 'BUILDING:PANDAGL', 'GL', 'NVIDIACG', 'CGGL']
     TargetAdd('pandagl_pandagl.obj', opts=OPTS, input='pandagl.cxx')
     TargetAdd('pandagl_pandagl.obj', opts=OPTS, input='pandagl.cxx')
     TargetAdd('libpandagl.dll', input='pandagl_pandagl.obj')
     TargetAdd('libpandagl.dll', input='pandagl_pandagl.obj')
     TargetAdd('libpandagl.dll', input='p3glgsg_config_glgsg.obj')
     TargetAdd('libpandagl.dll', input='p3glgsg_config_glgsg.obj')
     TargetAdd('libpandagl.dll', input='p3glgsg_glgsg.obj')
     TargetAdd('libpandagl.dll', input='p3glgsg_glgsg.obj')
     TargetAdd('libpandagl.dll', input='p3cocoadisplay_composite1.obj')
     TargetAdd('libpandagl.dll', input='p3cocoadisplay_composite1.obj')
+    TargetAdd('libpandagl.dll', input='p3cocoagldisplay_composite1.obj')
     if not PkgSkip('PANDAFX'):
     if not PkgSkip('PANDAFX'):
         TargetAdd('libpandagl.dll', input='libpandafx.dll')
         TargetAdd('libpandagl.dll', input='libpandafx.dll')
     TargetAdd('libpandagl.dll', input=COMMON_PANDA_LIBS)
     TargetAdd('libpandagl.dll', input=COMMON_PANDA_LIBS)

+ 1 - 0
panda/CMakeLists.txt

@@ -8,6 +8,7 @@ add_subdirectory(src/audiotraits)
 add_subdirectory(src/chan)
 add_subdirectory(src/chan)
 add_subdirectory(src/char)
 add_subdirectory(src/char)
 add_subdirectory(src/cocoadisplay)
 add_subdirectory(src/cocoadisplay)
+add_subdirectory(src/cocoagldisplay)
 add_subdirectory(src/collide)
 add_subdirectory(src/collide)
 add_subdirectory(src/configfiles)
 add_subdirectory(src/configfiles)
 add_subdirectory(src/cull)
 add_subdirectory(src/cull)

+ 3 - 3
panda/metalibs/pandagl/CMakeLists.txt

@@ -13,9 +13,9 @@ elseif(HAVE_WGL)
   set(PANDAGL_PIPE_TYPE "wglGraphicsPipe")
   set(PANDAGL_PIPE_TYPE "wglGraphicsPipe")
 
 
 elseif(HAVE_COCOA)
 elseif(HAVE_COCOA)
-  list(APPEND PANDAGL_LINK_TARGETS p3cocoadisplay)
-  set(PANDAGL_PIPE_TYPE "CocoaGraphicsPipe")
-  set(PANDAGL_PIPE_INCLUDE "cocoaGraphicsPipe.h")
+  list(APPEND PANDAGL_LINK_TARGETS p3cocoagldisplay p3cocoadisplay)
+  set(PANDAGL_PIPE_TYPE "CocoaGLGraphicsPipe")
+  set(PANDAGL_PIPE_INCLUDE "cocoaGLGraphicsPipe.h")
 
 
 else()
 else()
   message("") # Add extra line before error
   message("") # Add extra line before error

+ 7 - 7
panda/metalibs/pandagl/pandagl.cxx

@@ -13,9 +13,9 @@
 #include "wglGraphicsPipe.h"
 #include "wglGraphicsPipe.h"
 #endif
 #endif
 
 
-#if defined(HAVE_COCOA)
-#include "config_cocoadisplay.h"
-#include "cocoaGraphicsPipe.h"
+#ifdef HAVE_COCOA
+#include "config_cocoagldisplay.h"
+#include "cocoaGLGraphicsPipe.h"
 #endif
 #endif
 
 
 #ifdef HAVE_GLX
 #ifdef HAVE_GLX
@@ -46,8 +46,8 @@ init_libpandagl() {
   init_libwgldisplay();
   init_libwgldisplay();
 #endif  // HAVE_GL
 #endif  // HAVE_GL
 
 
-#if defined(HAVE_COCOA)
-  init_libcocoadisplay();
+#ifdef HAVE_COCOA
+  init_libcocoagldisplay();
 #endif
 #endif
 
 
 #ifdef HAVE_GLX
 #ifdef HAVE_GLX
@@ -69,8 +69,8 @@ get_pipe_type_pandagl() {
   return wglGraphicsPipe::get_class_type().get_index();
   return wglGraphicsPipe::get_class_type().get_index();
 #endif
 #endif
 
 
-#if defined(HAVE_COCOA)
-  return CocoaGraphicsPipe::get_class_type().get_index();
+#ifdef HAVE_COCOA
+  return CocoaGLGraphicsPipe::get_class_type().get_index();
 #endif
 #endif
 
 
 #ifdef HAVE_GLX
 #ifdef HAVE_GLX

+ 3 - 7
panda/src/cocoadisplay/CMakeLists.txt

@@ -1,13 +1,11 @@
-if(NOT APPLE OR NOT HAVE_GL OR NOT HAVE_COCOA)
+if(NOT APPLE OR NOT HAVE_COCOA)
   return()
   return()
 endif()
 endif()
 
 
 set(P3COCOADISPLAY_HEADERS
 set(P3COCOADISPLAY_HEADERS
   config_cocoadisplay.h
   config_cocoadisplay.h
-  cocoaGraphicsBuffer.h cocoaGraphicsBuffer.I
   cocoaGraphicsPipe.h cocoaGraphicsPipe.I
   cocoaGraphicsPipe.h cocoaGraphicsPipe.I
   cocoaGraphicsWindow.h cocoaGraphicsWindow.I
   cocoaGraphicsWindow.h cocoaGraphicsWindow.I
-  cocoaGraphicsStateGuardian.h cocoaGraphicsStateGuardian.I
   cocoaPandaApp.h
   cocoaPandaApp.h
   cocoaPandaView.h
   cocoaPandaView.h
   cocoaPandaWindow.h
   cocoaPandaWindow.h
@@ -17,9 +15,7 @@ set(P3COCOADISPLAY_HEADERS
 
 
 set(P3COCOADISPLAY_SOURCES
 set(P3COCOADISPLAY_SOURCES
   config_cocoadisplay.mm
   config_cocoadisplay.mm
-  cocoaGraphicsBuffer.mm
   cocoaGraphicsPipe.mm
   cocoaGraphicsPipe.mm
-  cocoaGraphicsStateGuardian.mm
   cocoaGraphicsWindow.mm
   cocoaGraphicsWindow.mm
   cocoaPandaApp.mm
   cocoaPandaApp.mm
   cocoaPandaView.mm
   cocoaPandaView.mm
@@ -31,7 +27,7 @@ set(P3COCOADISPLAY_SOURCES
 composite_sources(p3cocoadisplay P3COCOADISPLAY_SOURCES)
 composite_sources(p3cocoadisplay P3COCOADISPLAY_SOURCES)
 add_component_library(p3cocoadisplay SYMBOL BUILDING_PANDA_COCOADISPLAY
 add_component_library(p3cocoadisplay SYMBOL BUILDING_PANDA_COCOADISPLAY
   ${P3COCOADISPLAY_HEADERS} ${P3COCOADISPLAY_SOURCES})
   ${P3COCOADISPLAY_HEADERS} ${P3COCOADISPLAY_SOURCES})
-target_link_libraries(p3cocoadisplay p3glgsg panda)
+target_link_libraries(p3cocoadisplay panda)
 
 
 # Frameworks:
 # Frameworks:
 find_library(APPLICATIONSERVICES_LIBRARY ApplicationServices)
 find_library(APPLICATIONSERVICES_LIBRARY ApplicationServices)
@@ -46,5 +42,5 @@ mark_as_advanced(
   APPLICATIONSERVICES_LIBRARY APPKIT_LIBRARY CARBON_LIBRARY CORE_VIDEO_LIBRARY)
   APPLICATIONSERVICES_LIBRARY APPKIT_LIBRARY CARBON_LIBRARY CORE_VIDEO_LIBRARY)
 
 
 if(NOT BUILD_METALIBS)
 if(NOT BUILD_METALIBS)
-  install(TARGETS p3cocoadisplay EXPORT OpenGL COMPONENT OpenGL DESTINATION ${CMAKE_INSTALL_LIBDIR})
+  install(TARGETS p3cocoadisplay EXPORT Core COMPONENT Core DESTINATION ${CMAKE_INSTALL_LIBDIR})
 endif()
 endif()

+ 1 - 28
panda/src/cocoadisplay/cocoaGraphicsPipe.h

@@ -15,22 +15,12 @@
 #define COCOAGRAPHICSPIPE_H
 #define COCOAGRAPHICSPIPE_H
 
 
 #include "pandabase.h"
 #include "pandabase.h"
-#include "graphicsWindow.h"
 #include "graphicsPipe.h"
 #include "graphicsPipe.h"
-#include "lightMutex.h"
-#include "lightReMutex.h"
 
 
-#ifdef __OBJC__
-#import <AppKit/NSScreen.h>
-#else
-struct NSScreen;
-#endif
 #include <ApplicationServices/ApplicationServices.h>
 #include <ApplicationServices/ApplicationServices.h>
 
 
-class FrameBufferProperties;
-
 /**
 /**
- * This graphics pipe represents the interface for creating OpenGL graphics
+ * This graphics pipe represents the base class for pipes that create
  * windows on a Cocoa-based (e.g.  Mac OS X) client.
  * windows on a Cocoa-based (e.g.  Mac OS X) client.
  */
  */
 class EXPCL_PANDA_COCOADISPLAY CocoaGraphicsPipe : public GraphicsPipe {
 class EXPCL_PANDA_COCOADISPLAY CocoaGraphicsPipe : public GraphicsPipe {
@@ -40,32 +30,15 @@ public:
 
 
   INLINE CGDirectDisplayID get_display_id() const;
   INLINE CGDirectDisplayID get_display_id() const;
 
 
-  virtual std::string get_interface_name() const;
-  static PT(GraphicsPipe) pipe_constructor();
-
 public:
 public:
   virtual PreferredWindowThread get_preferred_window_thread() const;
   virtual PreferredWindowThread get_preferred_window_thread() const;
 
 
-protected:
-  virtual PT(GraphicsOutput) make_output(const std::string &name,
-                                         const FrameBufferProperties &fb_prop,
-                                         const WindowProperties &win_prop,
-                                         int flags,
-                                         GraphicsEngine *engine,
-                                         GraphicsStateGuardian *gsg,
-                                         GraphicsOutput *host,
-                                         int retry,
-                                         bool &precertify);
-  virtual PT(GraphicsStateGuardian) make_callback_gsg(GraphicsEngine *engine);
-
 private:
 private:
   void load_display_information();
   void load_display_information();
 
 
   // This is the Quartz display identifier.
   // This is the Quartz display identifier.
   CGDirectDisplayID _display;
   CGDirectDisplayID _display;
 
 
-  friend class CocoaGraphicsWindow;
-
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {
     return _type_handle;
     return _type_handle;

+ 1 - 120
panda/src/cocoadisplay/cocoaGraphicsPipe.mm

@@ -12,11 +12,7 @@
  */
  */
 
 
 #include "cocoaGraphicsPipe.h"
 #include "cocoaGraphicsPipe.h"
-#include "cocoaGraphicsBuffer.h"
-#include "cocoaGraphicsWindow.h"
-#include "cocoaGraphicsStateGuardian.h"
 #include "config_cocoadisplay.h"
 #include "config_cocoadisplay.h"
-#include "frameBufferProperties.h"
 #include "displayInformation.h"
 #include "displayInformation.h"
 
 
 #import <Foundation/NSAutoreleasePool.h>
 #import <Foundation/NSAutoreleasePool.h>
@@ -32,9 +28,6 @@ TypeHandle CocoaGraphicsPipe::_type_handle;
  */
  */
 CocoaGraphicsPipe::
 CocoaGraphicsPipe::
 CocoaGraphicsPipe(CGDirectDisplayID display) : _display(display) {
 CocoaGraphicsPipe(CGDirectDisplayID display) : _display(display) {
-  _supported_types = OT_window | OT_buffer | OT_texture_buffer;
-  _is_valid = true;
-
   [[NSAutoreleasePool alloc] init];
   [[NSAutoreleasePool alloc] init];
 
 
   // Put Cocoa into thread-safe mode by spawning a thread which immediately
   // Put Cocoa into thread-safe mode by spawning a thread which immediately
@@ -110,7 +103,7 @@ load_display_information() {
     }
     }
     CFRelease(encoding);
     CFRelease(encoding);
   }
   }
-  if (modes != NULL) {
+  if (modes != nullptr) {
     CFRelease(modes);
     CFRelease(modes);
   }
   }
 
 
@@ -135,26 +128,6 @@ CocoaGraphicsPipe::
 ~CocoaGraphicsPipe() {
 ~CocoaGraphicsPipe() {
 }
 }
 
 
-/**
- * Returns the name of the rendering interface associated with this
- * GraphicsPipe.  This is used to present to the user to allow him/her to
- * choose between several possible GraphicsPipes available on a particular
- * platform, so the name should be meaningful and unique for a given platform.
- */
-std::string CocoaGraphicsPipe::
-get_interface_name() const {
-  return "OpenGL";
-}
-
-/**
- * This function is passed to the GraphicsPipeSelection object to allow the
- * user to make a default CocoaGraphicsPipe.
- */
-PT(GraphicsPipe) CocoaGraphicsPipe::
-pipe_constructor() {
-  return new CocoaGraphicsPipe;
-}
-
 /**
 /**
  * Returns an indication of the thread in which this GraphicsPipe requires its
  * Returns an indication of the thread in which this GraphicsPipe requires its
  * window processing to be performed: typically either the app thread (e.g.
  * window processing to be performed: typically either the app thread (e.g.
@@ -166,95 +139,3 @@ CocoaGraphicsPipe::get_preferred_window_thread() const {
   // only be called from the main thread!
   // only be called from the main thread!
   return PWT_app;
   return PWT_app;
 }
 }
-
-/**
- * Creates a new window on the pipe, if possible.
- */
-PT(GraphicsOutput) CocoaGraphicsPipe::
-make_output(const std::string &name,
-            const FrameBufferProperties &fb_prop,
-            const WindowProperties &win_prop,
-            int flags,
-            GraphicsEngine *engine,
-            GraphicsStateGuardian *gsg,
-            GraphicsOutput *host,
-            int retry,
-            bool &precertify) {
-
-  if (!_is_valid) {
-    return NULL;
-  }
-
-  CocoaGraphicsStateGuardian *cocoagsg = 0;
-  if (gsg != 0) {
-    DCAST_INTO_R(cocoagsg, gsg, NULL);
-  }
-
-  // First thing to try: a CocoaGraphicsWindow
-
-  if (retry == 0) {
-    if (((flags&BF_require_parasite)!=0)||
-        ((flags&BF_refuse_window)!=0)||
-        ((flags&BF_resizeable)!=0)||
-        ((flags&BF_size_track_host)!=0)||
-        ((flags&BF_rtt_cumulative)!=0)||
-        ((flags&BF_can_bind_color)!=0)||
-        ((flags&BF_can_bind_every)!=0)||
-        ((flags&BF_can_bind_layered)!=0)) {
-      return NULL;
-    }
-    return new CocoaGraphicsWindow(engine, this, name, fb_prop, win_prop,
-                                   flags, gsg, host);
-  }
-
-  // Second thing to try: a GLGraphicsBuffer.  This requires a context, so if
-  // we don't have a host window, we instead create a CocoaGraphicsBuffer,
-  // which wraps around GLGraphicsBuffer and manages a context.
-
-  if (retry == 1) {
-    if (!gl_support_fbo ||
-        (flags & (BF_require_parasite | BF_require_window)) != 0) {
-      return NULL;
-    }
-    // Early failure - if we are sure that this buffer WONT meet specs, we can
-    // bail out early.
-    if ((flags & BF_fb_props_optional) == 0) {
-      if (fb_prop.get_indexed_color() ||
-          fb_prop.get_back_buffers() > 0 ||
-          fb_prop.get_accum_bits() > 0) {
-        return NULL;
-      }
-    }
-    if (cocoagsg != NULL && cocoagsg->is_valid() && !cocoagsg->needs_reset()) {
-      if (!cocoagsg->_supports_framebuffer_object ||
-          cocoagsg->_glDrawBuffers == NULL) {
-        return NULL;
-      } else if (fb_prop.is_basic()) {
-        // Early success - if we are sure that this buffer WILL meet specs, we
-        // can precertify it.
-        precertify = true;
-      }
-    }
-    if (host != NULL) {
-      return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
-                                  flags, gsg, host);
-    } else {
-      return new CocoaGraphicsBuffer(engine, this, name, fb_prop, win_prop,
-                                     flags, gsg, host);
-    }
-  }
-
-  // Nothing else left to try.
-  return NULL;
-}
-
-/**
- * This is called when make_output() is used to create a
- * CallbackGraphicsWindow.  If the GraphicsPipe can construct a GSG that's not
- * associated with any particular window object, do so now, assuming the
- * correct graphics context has been set up externally.
- */
-PT(GraphicsStateGuardian) CocoaGraphicsPipe::
-make_callback_gsg(GraphicsEngine *engine) {
-  return new CocoaGraphicsStateGuardian(engine, this, NULL);
-}

+ 15 - 6
panda/src/cocoadisplay/cocoaGraphicsWindow.h

@@ -19,11 +19,21 @@
 #include "cocoaGraphicsPipe.h"
 #include "cocoaGraphicsPipe.h"
 #include "graphicsWindow.h"
 #include "graphicsWindow.h"
 
 
+#ifdef __OBJC__
 #import <AppKit/NSEvent.h>
 #import <AppKit/NSEvent.h>
 #import <AppKit/NSView.h>
 #import <AppKit/NSView.h>
 #import <AppKit/NSWindow.h>
 #import <AppKit/NSWindow.h>
-
 #import <CoreVideo/CoreVideo.h>
 #import <CoreVideo/CoreVideo.h>
+#else
+#include <objc/objc.h>
+typedef objc_object NSCursor;
+typedef objc_object NSData;
+typedef objc_object NSEvent;
+typedef objc_object NSImage;
+typedef objc_object NSView;
+typedef objc_object NSWindow;
+typedef unsigned long NSUInteger;
+#endif
 
 
 /**
 /**
  * An interface to the Cocoa system for managing OpenGL windows under Mac OS
  * An interface to the Cocoa system for managing OpenGL windows under Mac OS
@@ -41,13 +51,13 @@ public:
   virtual ~CocoaGraphicsWindow();
   virtual ~CocoaGraphicsWindow();
 
 
   virtual bool move_pointer(int device, int x, int y);
   virtual bool move_pointer(int device, int x, int y);
-  virtual bool begin_frame(FrameMode mode, Thread *current_thread);
-  virtual void end_frame(FrameMode mode, Thread *current_thread);
-  virtual void end_flip();
 
 
   virtual void process_events();
   virtual void process_events();
   virtual void set_properties_now(WindowProperties &properties);
   virtual void set_properties_now(WindowProperties &properties);
 
 
+  virtual void update_context();
+  virtual void unbind_context();
+
   void handle_move_event();
   void handle_move_event();
   void handle_resize_event();
   void handle_resize_event();
   void handle_minimize_event(bool minimized);
   void handle_minimize_event(bool minimized);
@@ -81,7 +91,7 @@ private:
   ButtonHandle map_key(unsigned short c) const;
   ButtonHandle map_key(unsigned short c) const;
   ButtonHandle map_raw_key(unsigned short keycode) const;
   ButtonHandle map_raw_key(unsigned short keycode) const;
 
 
-private:
+protected:
   NSWindow *_window;
   NSWindow *_window;
   NSView *_view;
   NSView *_view;
   NSUInteger _modifier_keys;
   NSUInteger _modifier_keys;
@@ -90,7 +100,6 @@ private:
   PT(GraphicsWindowInputDevice) _input;
   PT(GraphicsWindowInputDevice) _input;
   bool _mouse_hidden;
   bool _mouse_hidden;
   bool _context_needs_update;
   bool _context_needs_update;
-  bool _vsync_enabled = false;
 
 
   CGDisplayModeRef _fullscreen_mode;
   CGDisplayModeRef _fullscreen_mode;
   CGDisplayModeRef _windowed_mode;
   CGDisplayModeRef _windowed_mode;

+ 26 - 244
panda/src/cocoadisplay/cocoaGraphicsWindow.mm

@@ -12,7 +12,6 @@
  */
  */
 
 
 #include "cocoaGraphicsWindow.h"
 #include "cocoaGraphicsWindow.h"
-#include "cocoaGraphicsStateGuardian.h"
 #include "config_cocoadisplay.h"
 #include "config_cocoadisplay.h"
 #include "cocoaGraphicsPipe.h"
 #include "cocoaGraphicsPipe.h"
 #include "cocoaPandaApp.h"
 #include "cocoaPandaApp.h"
@@ -40,7 +39,6 @@
 #import <AppKit/NSImage.h>
 #import <AppKit/NSImage.h>
 #import <AppKit/NSScreen.h>
 #import <AppKit/NSScreen.h>
 #import <AppKit/NSText.h>
 #import <AppKit/NSText.h>
-#import <OpenGL/OpenGL.h>
 #import <Carbon/Carbon.h>
 #import <Carbon/Carbon.h>
 
 
 TypeHandle CocoaGraphicsWindow::_type_handle;
 TypeHandle CocoaGraphicsWindow::_type_handle;
@@ -108,7 +106,7 @@ CocoaGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
 
 
   CocoaGraphicsPipe *cocoa_pipe;
   CocoaGraphicsPipe *cocoa_pipe;
   DCAST_INTO_V(cocoa_pipe, _pipe);
   DCAST_INTO_V(cocoa_pipe, _pipe);
-  _display = cocoa_pipe->_display;
+  _display = cocoa_pipe->get_display_id();
 }
 }
 
 
 /**
 /**
@@ -161,147 +159,6 @@ move_pointer(int device, int x, int y) {
   return false;
   return false;
 }
 }
 
 
-
-/**
- * This function will be called within the draw thread before beginning
- * rendering for a given frame.  It should do whatever setup is required, and
- * return true if the frame should be rendered, or false if it should be
- * skipped.
- */
-bool CocoaGraphicsWindow::
-begin_frame(FrameMode mode, Thread *current_thread) {
-  PStatTimer timer(_make_current_pcollector, current_thread);
-
-  begin_frame_spam(mode);
-  if (_gsg == (GraphicsStateGuardian *)NULL) {
-    return false;
-  }
-
-  CocoaGraphicsStateGuardian *cocoagsg;
-  DCAST_INTO_R(cocoagsg, _gsg, false);
-  nassertr(cocoagsg->_context != nil, false);
-  nassertr(_view != nil, false);
-
-  // Place a lock on the context.
-  cocoagsg->lock_context();
-
-  // Set the drawable.
-  // Although not recommended, it is technically possible to use the same
-  // context with multiple different-sized windows.  If that happens, the
-  // context needs to be updated accordingly.
-  if ([cocoagsg->_context view] != _view) {
-    // XXX I'm not 100% sure that changing the view requires it to update.
-    _context_needs_update = true;
-    [cocoagsg->_context setView:_view];
-
-    if (cocoadisplay_cat.is_spam()) {
-      cocoadisplay_cat.spam()
-        << "Switching context to view " << _view << "\n";
-    }
-  }
-
-  // Update the context if necessary, to make it reallocate buffers etc.
-  if (_context_needs_update) {
-    if ([NSThread isMainThread]) {
-      [cocoagsg->_context update];
-      _context_needs_update = false;
-    } else {
-      cocoagsg->unlock_context();
-      return false;
-    }
-  }
-
-  // Lock the view for drawing.
-  if (!_properties.get_fullscreen()) {
-    nassertr_always([_view lockFocusIfCanDraw], false);
-  }
-
-  // Make the context current.
-  [cocoagsg->_context makeCurrentContext];
-
-  // Now that we have made the context current to a window, we can reset the
-  // GSG state if this is the first time it has been used.  (We can't just
-  // call reset() when we construct the GSG, because reset() requires having a
-  // current context.)
-  cocoagsg->reset_if_new();
-
-  if (mode == FM_render) {
-    // begin_render_texture();
-    clear_cube_map_selection();
-  }
-
-  _gsg->set_current_properties(&get_fb_properties());
-  return _gsg->begin_frame(current_thread);
-}
-
-/**
- * This function will be called within the draw thread after rendering is
- * completed for a given frame.  It should do whatever finalization is
- * required.
- */
-void CocoaGraphicsWindow::
-end_frame(FrameMode mode, Thread *current_thread) {
-  end_frame_spam(mode);
-  nassertv(_gsg != (GraphicsStateGuardian *)NULL);
-
-  if (!_properties.get_fullscreen()) {
-    [_view unlockFocus];
-  }
-  // Release the context.
-  CocoaGraphicsStateGuardian *cocoagsg;
-  DCAST_INTO_V(cocoagsg, _gsg);
-
-  cocoagsg->unlock_context();
-
-  if (mode == FM_render) {
-    // end_render_texture();
-    copy_to_textures();
-  }
-
-  _gsg->end_frame(current_thread);
-
-  if (mode == FM_render) {
-    trigger_flip();
-    clear_cube_map_selection();
-  }
-}
-
-/**
- * This function will be called within the draw thread after begin_flip() has
- * been called on all windows, to finish the exchange of the front and back
- * buffers.
- *
- * This should cause the window to wait for the flip, if necessary.
- */
-void CocoaGraphicsWindow::
-end_flip() {
-  if (_gsg != (GraphicsStateGuardian *)NULL && _flip_ready) {
-
-    CocoaGraphicsStateGuardian *cocoagsg;
-    DCAST_INTO_V(cocoagsg, _gsg);
-
-    if (_vsync_enabled) {
-      AtomicAdjust::Integer cur_frame = ClockObject::get_global_clock()->get_frame_count();
-      if (AtomicAdjust::set(cocoagsg->_last_wait_frame, cur_frame) != cur_frame) {
-        cocoagsg->_swap_lock.lock();
-        cocoagsg->_swap_condition.wait();
-        cocoagsg->_swap_lock.unlock();
-      }
-    }
-
-    cocoagsg->lock_context();
-
-    // Swap the front and back buffer.
-    [cocoagsg->_context flushBuffer];
-
-    // Flush the window
-    [[_view window] flushWindow];
-
-    cocoagsg->unlock_context();
-  }
-  GraphicsWindow::end_flip();
-}
-
 /**
 /**
  * Do whatever processing is necessary to ensure that the window responds to
  * Do whatever processing is necessary to ensure that the window responds to
  * user events.  Also, honor any requests recently made via
  * user events.  Also, honor any requests recently made via
@@ -351,15 +208,7 @@ process_events() {
   [pool release];
   [pool release];
 
 
   if (_context_needs_update && _gsg != nullptr) {
   if (_context_needs_update && _gsg != nullptr) {
-    CocoaGraphicsStateGuardian *cocoagsg;
-    DCAST_INTO_V(cocoagsg, _gsg);
-
-    if (cocoagsg != nullptr && cocoagsg->_context != nil) {
-      cocoagsg->lock_context();
-      _context_needs_update = false;
-      [cocoagsg->_context update];
-      cocoagsg->unlock_context();
-    }
+    update_context();
   }
   }
 }
 }
 
 
@@ -369,34 +218,6 @@ process_events() {
  */
  */
 bool CocoaGraphicsWindow::
 bool CocoaGraphicsWindow::
 open_window() {
 open_window() {
-  CocoaGraphicsPipe *cocoa_pipe;
-  DCAST_INTO_R(cocoa_pipe, _pipe, false);
-
-  // GSG CreationInitialization
-  CocoaGraphicsStateGuardian *cocoagsg;
-  if (_gsg == 0) {
-    // There is no old gsg.  Create a new one.
-    cocoagsg = new CocoaGraphicsStateGuardian(_engine, _pipe, NULL);
-    cocoagsg->choose_pixel_format(_fb_properties, cocoa_pipe->_display, false);
-    _gsg = cocoagsg;
-  } else {
-    // If the old gsg has the wrong pixel format, create a new one that shares
-    // with the old gsg.
-    DCAST_INTO_R(cocoagsg, _gsg, false);
-    if (!cocoagsg->get_fb_properties().subsumes(_fb_properties)) {
-      cocoagsg = new CocoaGraphicsStateGuardian(_engine, _pipe, cocoagsg);
-      cocoagsg->choose_pixel_format(_fb_properties, cocoa_pipe->_display, false);
-      _gsg = cocoagsg;
-    }
-  }
-
-  if (cocoagsg->_context == nil) {
-    // Could not obtain a proper context.
-    _gsg.clear();
-    close_window();
-    return false;
-  }
-
   // Fill in the blanks.
   // Fill in the blanks.
   if (!_properties.has_origin()) {
   if (!_properties.has_origin()) {
     _properties.set_origin(-2, -2);
     _properties.set_origin(-2, -2);
@@ -476,7 +297,7 @@ open_window() {
   NSEnumerator *e = [[NSScreen screens] objectEnumerator];
   NSEnumerator *e = [[NSScreen screens] objectEnumerator];
   while (screen = (NSScreen *) [e nextObject]) {
   while (screen = (NSScreen *) [e nextObject]) {
     NSNumber *num = [[screen deviceDescription] objectForKey: @"NSScreenNumber"];
     NSNumber *num = [[screen deviceDescription] objectForKey: @"NSScreenNumber"];
-    if (cocoa_pipe->_display == (CGDirectDisplayID) [num longValue]) {
+    if (_display == (CGDirectDisplayID) [num longValue]) {
       break;
       break;
     }
     }
   }
   }
@@ -545,19 +366,16 @@ open_window() {
     }
     }
   }
   }
 
 
-  // Lock the context, so we can safely operate on it.
-  cocoagsg->lock_context();
-
   // Create the NSView to render to.
   // Create the NSView to render to.
   NSRect rect = NSMakeRect(0, 0, _properties.get_x_size(), _properties.get_y_size());
   NSRect rect = NSMakeRect(0, 0, _properties.get_x_size(), _properties.get_y_size());
-  _view = [[CocoaPandaView alloc] initWithFrame:rect context:cocoagsg->_context window:this];
-  if (_parent_window_handle == (WindowHandle *)NULL) {
+  _view = [[CocoaPandaView alloc] initWithFrame:rect window:this];
+  if (_parent_window_handle == nullptr) {
     [_window setContentView:_view];
     [_window setContentView:_view];
     [_window makeFirstResponder:_view];
     [_window makeFirstResponder:_view];
   }
   }
 
 
   // Check if we have an NSView to attach our NSView to.
   // Check if we have an NSView to attach our NSView to.
-  if (parent_nsview != NULL) {
+  if (parent_nsview != nullptr) {
     [parent_nsview addSubview:_view];
     [parent_nsview addSubview:_view];
   }
   }
 
 
@@ -566,7 +384,7 @@ open_window() {
   _window_handle = NativeWindowHandle::make_int((size_t) _view);
   _window_handle = NativeWindowHandle::make_int((size_t) _view);
 
 
   // And tell our parent window that we're now its child.
   // And tell our parent window that we're now its child.
-  if (_parent_window_handle != (WindowHandle *)NULL) {
+  if (_parent_window_handle != nullptr) {
     _parent_window_handle->attach_child(_window_handle);
     _parent_window_handle->attach_child(_window_handle);
   }
   }
 
 
@@ -672,29 +490,6 @@ open_window() {
     }
     }
   }
   }
 
 
-  // Make the context current.
-  _context_needs_update = false;
-  [cocoagsg->_context makeCurrentContext];
-  [cocoagsg->_context setView:_view];
-  [cocoagsg->_context update];
-
-  cocoagsg->reset_if_new();
-
-  // Release the context.
-  cocoagsg->unlock_context();
-
-  if (!cocoagsg->is_valid()) {
-    close_window();
-    return false;
-  }
-
-  if (!cocoagsg->get_fb_properties().verify_hardware_software
-      (_fb_properties, cocoagsg->get_gl_renderer())) {
-    close_window();
-    return false;
-  }
-  _fb_properties = cocoagsg->get_fb_properties();
-
   // Reset dead key state.
   // Reset dead key state.
   _dead_key_state = 0;
   _dead_key_state = 0;
 
 
@@ -710,8 +505,6 @@ open_window() {
     CGAssociateMouseAndMouseCursorPosition(NO);
     CGAssociateMouseAndMouseCursorPosition(NO);
   }
   }
 
 
-  _vsync_enabled = sync_video && cocoagsg->setup_vsync();
-
   return true;
   return true;
 }
 }
 
 
@@ -730,15 +523,8 @@ close_window() {
     _cursor = nil;
     _cursor = nil;
   }
   }
 
 
-  if (_gsg != (GraphicsStateGuardian *)NULL) {
-    CocoaGraphicsStateGuardian *cocoagsg;
-    cocoagsg = DCAST(CocoaGraphicsStateGuardian, _gsg);
-
-    if (cocoagsg != NULL && cocoagsg->_context != nil) {
-      cocoagsg->lock_context();
-      [cocoagsg->_context clearDrawable];
-      cocoagsg->unlock_context();
-    }
+  if (_gsg != nullptr) {
+    unbind_context();
     _gsg.clear();
     _gsg.clear();
   }
   }
 
 
@@ -756,8 +542,6 @@ close_window() {
     _view = nil;
     _view = nil;
   }
   }
 
 
-  _vsync_enabled = false;
-
   GraphicsWindow::close_window();
   GraphicsWindow::close_window();
 }
 }
 
 
@@ -1148,18 +932,24 @@ set_properties_now(WindowProperties &properties) {
   }
   }
 
 
   if (_context_needs_update && _gsg != nullptr) {
   if (_context_needs_update && _gsg != nullptr) {
-    CocoaGraphicsStateGuardian *cocoagsg;
-    DCAST_INTO_V(cocoagsg, _gsg);
-
-    if (cocoagsg != nullptr && cocoagsg->_context != nil) {
-      cocoagsg->lock_context();
-      _context_needs_update = false;
-      [cocoagsg->_context update];
-      cocoagsg->unlock_context();
-    }
+    update_context();
   }
   }
 }
 }
 
 
+/**
+ *
+ */
+void CocoaGraphicsWindow::
+update_context() {
+}
+
+/**
+ *
+ */
+void CocoaGraphicsWindow::
+unbind_context() {
+}
+
 /**
 /**
  * Returns an appropriate CGDisplayModeRef for the given width and height, or
  * Returns an appropriate CGDisplayModeRef for the given width and height, or
  * NULL if none was found.
  * NULL if none was found.
@@ -1663,17 +1453,9 @@ handle_close_event() {
   _window = nil;
   _window = nil;
 
 
   // Get rid of the GSG
   // Get rid of the GSG
-  if (_gsg != (GraphicsStateGuardian *)NULL) {
-    CocoaGraphicsStateGuardian *cocoagsg;
-    cocoagsg = DCAST(CocoaGraphicsStateGuardian, _gsg);
-
-    if (cocoagsg != NULL && cocoagsg->_context != nil) {
-      cocoagsg->lock_context();
-      [cocoagsg->_context clearDrawable];
-      cocoagsg->unlock_context();
-    }
+  if (_gsg != nullptr) {
+    unbind_context();
     _gsg.clear();
     _gsg.clear();
-    _vsync_enabled = false;
   }
   }
 
 
   // Dump the view, too
   // Dump the view, too

+ 154 - 0
panda/src/cocoadisplay/cocoaGraphicsWindow.mm.rej

@@ -0,0 +1,154 @@
+diff a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm	(rejected hunks)
+@@ -161,152 +159,6 @@
+   return false;
+ }
+ 
+-
+-/**
+- * This function will be called within the draw thread before beginning
+- * rendering for a given frame.  It should do whatever setup is required, and
+- * return true if the frame should be rendered, or false if it should be
+- * skipped.
+- */
+-bool CocoaGraphicsWindow::
+-begin_frame(FrameMode mode, Thread *current_thread) {
+-  PStatTimer timer(_make_current_pcollector, current_thread);
+-
+-  begin_frame_spam(mode);
+-  if (_gsg == (GraphicsStateGuardian *)NULL) {
+-    return false;
+-  }
+-
+-  CocoaGraphicsStateGuardian *cocoagsg;
+-  DCAST_INTO_R(cocoagsg, _gsg, false);
+-  nassertr(cocoagsg->_context != nil, false);
+-  nassertr(_view != nil, false);
+-
+-  // Place a lock on the context.
+-  cocoagsg->lock_context();
+-
+-  // Set the drawable.
+-  // Although not recommended, it is technically possible to use the same
+-  // context with multiple different-sized windows.  If that happens, the
+-  // context needs to be updated accordingly.
+-  if ([cocoagsg->_context view] != _view) {
+-    // XXX I'm not 100% sure that changing the view requires it to update.
+-    _context_needs_update = true;
+-    [cocoagsg->_context setView:_view];
+-
+-    if (cocoadisplay_cat.is_spam()) {
+-      cocoadisplay_cat.spam()
+-        << "Switching context to view " << _view << "\n";
+-    }
+-  }
+-
+-  // Update the context if necessary, to make it reallocate buffers etc.
+-  if (_context_needs_update) {
+-    if ([NSThread isMainThread]) {
+-      [cocoagsg->_context update];
+-      _context_needs_update = false;
+-    } else {
+-      cocoagsg->unlock_context();
+-      return false;
+-    }
+-  }
+-
+-  // Lock the view for drawing.
+-  if (!_properties.get_fullscreen()) {
+-    nassertr_always([_view lockFocusIfCanDraw], false);
+-  }
+-
+-  // Make the context current.
+-  [cocoagsg->_context makeCurrentContext];
+-
+-  // Now that we have made the context current to a window, we can reset the
+-  // GSG state if this is the first time it has been used.  (We can't just
+-  // call reset() when we construct the GSG, because reset() requires having a
+-  // current context.)
+-  cocoagsg->reset_if_new();
+-
+-  if (mode == FM_render) {
+-    // begin_render_texture();
+-    clear_cube_map_selection();
+-  }
+-
+-  _gsg->set_current_properties(&get_fb_properties());
+-  if (_gsg->begin_frame(current_thread)) {
+-    copy_async_screenshot();
+-    return true;
+-  } else {
+-    return false;
+-  }
+-}
+-
+-/**
+- * This function will be called within the draw thread after rendering is
+- * completed for a given frame.  It should do whatever finalization is
+- * required.
+- */
+-void CocoaGraphicsWindow::
+-end_frame(FrameMode mode, Thread *current_thread) {
+-  end_frame_spam(mode);
+-  nassertv(_gsg != (GraphicsStateGuardian *)NULL);
+-
+-  if (!_properties.get_fullscreen()) {
+-    [_view unlockFocus];
+-  }
+-  // Release the context.
+-  CocoaGraphicsStateGuardian *cocoagsg;
+-  DCAST_INTO_V(cocoagsg, _gsg);
+-
+-  cocoagsg->unlock_context();
+-
+-  if (mode == FM_render) {
+-    // end_render_texture();
+-    copy_to_textures();
+-  }
+-
+-  _gsg->end_frame(current_thread);
+-
+-  if (mode == FM_render) {
+-    trigger_flip();
+-    clear_cube_map_selection();
+-  }
+-}
+-
+-/**
+- * This function will be called within the draw thread after begin_flip() has
+- * been called on all windows, to finish the exchange of the front and back
+- * buffers.
+- *
+- * This should cause the window to wait for the flip, if necessary.
+- */
+-void CocoaGraphicsWindow::
+-end_flip() {
+-  if (_gsg != (GraphicsStateGuardian *)NULL && _flip_ready) {
+-
+-    CocoaGraphicsStateGuardian *cocoagsg;
+-    DCAST_INTO_V(cocoagsg, _gsg);
+-
+-    if (_vsync_enabled) {
+-      AtomicAdjust::Integer cur_frame = ClockObject::get_global_clock()->get_frame_count();
+-      if (AtomicAdjust::set(cocoagsg->_last_wait_frame, cur_frame) != cur_frame) {
+-        cocoagsg->_swap_lock.lock();
+-        cocoagsg->_swap_condition.wait();
+-        cocoagsg->_swap_lock.unlock();
+-      }
+-    }
+-
+-    cocoagsg->lock_context();
+-
+-    // Swap the front and back buffer.
+-    [cocoagsg->_context flushBuffer];
+-
+-    // Flush the window
+-    [[_view window] flushWindow];
+-
+-    cocoagsg->unlock_context();
+-  }
+-  GraphicsWindow::end_flip();
+-}
+-
+ /**
+  * Do whatever processing is necessary to ensure that the window responds to
+  * user events.  Also, honor any requests recently made via

+ 1 - 4
panda/src/cocoadisplay/cocoaPandaView.h

@@ -14,18 +14,15 @@
 #include "graphicsWindow.h"
 #include "graphicsWindow.h"
 
 
 #import <AppKit/NSView.h>
 #import <AppKit/NSView.h>
-#import <AppKit/NSOpenGL.h>
 
 
 class CocoaGraphicsWindow;
 class CocoaGraphicsWindow;
 
 
 @interface CocoaPandaView : NSView {
 @interface CocoaPandaView : NSView {
   @private
   @private
-    NSOpenGLContext *_context;
     CocoaGraphicsWindow *_graphicsWindow;
     CocoaGraphicsWindow *_graphicsWindow;
 }
 }
 
 
-- (id) initWithFrame:(NSRect)frameRect context:(NSOpenGLContext*)context window:(CocoaGraphicsWindow*)window;
-- (NSOpenGLContext*) openGLContext;
+- (id) initWithFrame:(NSRect)frameRect window:(CocoaGraphicsWindow*)window;
 - (GraphicsWindow*) graphicsWindow;
 - (GraphicsWindow*) graphicsWindow;
 
 
 - (void) drawRect:(NSRect)dirtyRect;
 - (void) drawRect:(NSRect)dirtyRect;

+ 4 - 14
panda/src/cocoadisplay/cocoaPandaView.mm

@@ -18,10 +18,9 @@
 #include <OpenGL/gl.h>
 #include <OpenGL/gl.h>
 
 
 @implementation CocoaPandaView
 @implementation CocoaPandaView
-- (id) initWithFrame:(NSRect)frameRect context:(NSOpenGLContext*)context window:(CocoaGraphicsWindow*)window {
+- (id) initWithFrame:(NSRect)frameRect window:(CocoaGraphicsWindow*)window {
   self = [super initWithFrame: frameRect];
   self = [super initWithFrame: frameRect];
 
 
-  _context = context;
   [self setCanDrawConcurrently:YES];
   [self setCanDrawConcurrently:YES];
 
 
   // If a layer ends up becoming attached to the view, tell AppKit we'll manage
   // If a layer ends up becoming attached to the view, tell AppKit we'll manage
@@ -37,10 +36,6 @@
   return self;
   return self;
 }
 }
 
 
-- (NSOpenGLContext*) openGLContext {
-  return _context;
-}
-
 - (GraphicsWindow*) graphicsWindow {
 - (GraphicsWindow*) graphicsWindow {
   return _graphicsWindow;
   return _graphicsWindow;
 }
 }
@@ -170,14 +165,9 @@
   return YES;
   return YES;
 }
 }
 
 
--(void)setLayer:(CALayer*)layer
-{
-    [super setLayer:layer];
+-(void)setLayer:(CALayer*)layer {
+  [super setLayer:layer];
 
 
-    // Starting in macOS 10.14, a CALayer will still be attached to a view even
-    // if `wantsLayer` is false. If we don't update the context now, only a
-    // black screen will be rendered until the context is updated some other
-    // way (like through a window resize event).
-    [_context update];
+  _graphicsWindow->update_context();
 }
 }
 @end
 @end

+ 0 - 12
panda/src/cocoadisplay/config_cocoadisplay.mm

@@ -12,11 +12,8 @@
  */
  */
 
 
 #include "config_cocoadisplay.h"
 #include "config_cocoadisplay.h"
-#include "cocoaGraphicsBuffer.h"
 #include "cocoaGraphicsPipe.h"
 #include "cocoaGraphicsPipe.h"
-#include "cocoaGraphicsStateGuardian.h"
 #include "cocoaGraphicsWindow.h"
 #include "cocoaGraphicsWindow.h"
-#include "graphicsPipeSelection.h"
 #include "dconfig.h"
 #include "dconfig.h"
 #include "pandaSystem.h"
 #include "pandaSystem.h"
 
 
@@ -50,15 +47,6 @@ init_libcocoadisplay() {
   }
   }
   initialized = true;
   initialized = true;
 
 
-  CocoaGraphicsBuffer::init_type();
   CocoaGraphicsPipe::init_type();
   CocoaGraphicsPipe::init_type();
-  CocoaGraphicsStateGuardian::init_type();
   CocoaGraphicsWindow::init_type();
   CocoaGraphicsWindow::init_type();
-
-  GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr();
-  selection->add_pipe_type(CocoaGraphicsPipe::get_class_type(),
-                           CocoaGraphicsPipe::pipe_constructor);
-
-  PandaSystem *ps = PandaSystem::get_global_ptr();
-  ps->set_system_tag("OpenGL", "window_system", "Cocoa");
 }
 }

+ 1 - 3
panda/src/cocoadisplay/p3cocoadisplay_composite1.mm

@@ -1,10 +1,8 @@
-#include "config_cocoadisplay.mm"
-#include "cocoaGraphicsBuffer.mm"
 #include "cocoaGraphicsPipe.mm"
 #include "cocoaGraphicsPipe.mm"
-#include "cocoaGraphicsStateGuardian.mm"
 #include "cocoaGraphicsWindow.mm"
 #include "cocoaGraphicsWindow.mm"
 #include "cocoaPandaApp.mm"
 #include "cocoaPandaApp.mm"
 #include "cocoaPandaView.mm"
 #include "cocoaPandaView.mm"
 #include "cocoaPandaWindow.mm"
 #include "cocoaPandaWindow.mm"
 #include "cocoaPandaWindowDelegate.mm"
 #include "cocoaPandaWindowDelegate.mm"
 #include "cocoaPandaAppDelegate.mm"
 #include "cocoaPandaAppDelegate.mm"
+#include "config_cocoadisplay.mm"

+ 28 - 0
panda/src/cocoagldisplay/CMakeLists.txt

@@ -0,0 +1,28 @@
+if(NOT APPLE OR NOT HAVE_GL OR NOT HAVE_COCOA)
+  return()
+endif()
+
+set(P3COCOAGLDISPLAY_HEADERS
+  cocoaGLGraphicsBuffer.h cocoaGLGraphicsBuffer.I
+  cocoaGLGraphicsPipe.h cocoaGLGraphicsPipe.I
+  cocoaGLGraphicsStateGuardian.h cocoaGLGraphicsStateGuardian.I
+  cocoaGLGraphicsWindow.h cocoaGLGraphicsWindow.I
+  config_cocoagldisplay.h
+)
+
+set(P3COCOAGLDISPLAY_SOURCES
+  cocoaGLGraphicsBuffer.mm
+  cocoaGLGraphicsPipe.mm
+  cocoaGLGraphicsStateGuardian.mm
+  cocoaGLGraphicsWindow.mm
+  config_cocoagldisplay.mm
+)
+
+composite_sources(p3cocoagldisplay P3COCOAGLDISPLAY_SOURCES)
+add_component_library(p3cocoagldisplay SYMBOL BUILDING_PANDA_COCOAGLDISPLAY
+  ${P3COCOAGLDISPLAY_HEADERS} ${P3COCOAGLDISPLAY_SOURCES})
+target_link_libraries(p3cocoagldisplay p3cocoadisplay p3glgsg panda)
+
+if(NOT BUILD_METALIBS)
+  install(TARGETS p3cocoagldisplay EXPORT OpenGL COMPONENT OpenGL DESTINATION ${CMAKE_INSTALL_LIBDIR})
+endif()

+ 1 - 1
panda/src/cocoadisplay/cocoaGraphicsBuffer.I → panda/src/cocoagldisplay/cocoaGLGraphicsBuffer.I

@@ -6,7 +6,7 @@
  * license.  You should have received a copy of this license along
  * license.  You should have received a copy of this license along
  * with this source code in a file named "LICENSE."
  * with this source code in a file named "LICENSE."
  *
  *
- * @file cocoaGraphicsBuffer.I
+ * @file cocoaGLGraphicsBuffer.I
  * @author rdb
  * @author rdb
  * @date 2017-12-19
  * @date 2017-12-19
  */
  */

+ 11 - 11
panda/src/cocoadisplay/cocoaGraphicsBuffer.h → panda/src/cocoagldisplay/cocoaGLGraphicsBuffer.h

@@ -6,7 +6,7 @@
  * license.  You should have received a copy of this license along
  * license.  You should have received a copy of this license along
  * with this source code in a file named "LICENSE."
  * with this source code in a file named "LICENSE."
  *
  *
- * @file cocoaGraphicsBuffer.h
+ * @file cocoaGLGraphicsBuffer.h
  * @author rdb
  * @author rdb
  * @date 2017-12-19
  * @date 2017-12-19
  */
  */
@@ -21,15 +21,15 @@
  * This is a light wrapper around GLGraphicsBuffer (ie. FBOs) to interface
  * This is a light wrapper around GLGraphicsBuffer (ie. FBOs) to interface
  * with Cocoa contexts, so that it can be used without a host window.
  * with Cocoa contexts, so that it can be used without a host window.
  */
  */
-class EXPCL_PANDA_COCOADISPLAY CocoaGraphicsBuffer : public GLGraphicsBuffer {
+class EXPCL_PANDA_COCOAGLDISPLAY CocoaGLGraphicsBuffer : public GLGraphicsBuffer {
 public:
 public:
-  CocoaGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
-                      const std::string &name,
-                      const FrameBufferProperties &fb_prop,
-                      const WindowProperties &win_prop,
-                      int flags,
-                      GraphicsStateGuardian *gsg,
-                      GraphicsOutput *host);
+  CocoaGLGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
+                        const std::string &name,
+                        const FrameBufferProperties &fb_prop,
+                        const WindowProperties &win_prop,
+                        int flags,
+                        GraphicsStateGuardian *gsg,
+                        GraphicsOutput *host);
 
 
   virtual bool begin_frame(FrameMode mode, Thread *current_thread);
   virtual bool begin_frame(FrameMode mode, Thread *current_thread);
   virtual void end_frame(FrameMode mode, Thread *current_thread);
   virtual void end_frame(FrameMode mode, Thread *current_thread);
@@ -44,7 +44,7 @@ public:
   }
   }
   static void init_type() {
   static void init_type() {
     GLGraphicsBuffer::init_type();
     GLGraphicsBuffer::init_type();
-    register_type(_type_handle, "CocoaGraphicsBuffer",
+    register_type(_type_handle, "CocoaGLGraphicsBuffer",
                   GLGraphicsBuffer::get_class_type());
                   GLGraphicsBuffer::get_class_type());
   }
   }
   virtual TypeHandle get_type() const {
   virtual TypeHandle get_type() const {
@@ -56,6 +56,6 @@ private:
   static TypeHandle _type_handle;
   static TypeHandle _type_handle;
 };
 };
 
 
-#include "cocoaGraphicsBuffer.I"
+#include "cocoaGLGraphicsBuffer.I"
 
 
 #endif
 #endif

+ 17 - 17
panda/src/cocoadisplay/cocoaGraphicsBuffer.mm → panda/src/cocoagldisplay/cocoaGLGraphicsBuffer.mm

@@ -6,25 +6,25 @@
  * license.  You should have received a copy of this license along
  * license.  You should have received a copy of this license along
  * with this source code in a file named "LICENSE."
  * with this source code in a file named "LICENSE."
  *
  *
- * @file cocoaGraphicsBuffer.mm
+ * @file cocoaGLGraphicsBuffer.mm
  * @author rdb
  * @author rdb
  * @date 2017-12-19
  * @date 2017-12-19
  */
  */
 
 
-#include "cocoaGraphicsBuffer.h"
-#include "cocoaGraphicsStateGuardian.h"
+#include "cocoaGLGraphicsBuffer.h"
+#include "cocoaGLGraphicsStateGuardian.h"
 #include "config_cocoadisplay.h"
 #include "config_cocoadisplay.h"
 #include "cocoaGraphicsPipe.h"
 #include "cocoaGraphicsPipe.h"
 
 
 #import <OpenGL/OpenGL.h>
 #import <OpenGL/OpenGL.h>
 
 
-TypeHandle CocoaGraphicsBuffer::_type_handle;
+TypeHandle CocoaGLGraphicsBuffer::_type_handle;
 
 
 /**
 /**
  *
  *
  */
  */
-CocoaGraphicsBuffer::
-CocoaGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
+CocoaGLGraphicsBuffer::
+CocoaGLGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
                     const std::string &name,
                     const std::string &name,
                     const FrameBufferProperties &fb_prop,
                     const FrameBufferProperties &fb_prop,
                     const WindowProperties &win_prop,
                     const WindowProperties &win_prop,
@@ -41,13 +41,13 @@ CocoaGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
  * return true if the frame should be rendered, or false if it should be
  * return true if the frame should be rendered, or false if it should be
  * skipped.
  * skipped.
  */
  */
-bool CocoaGraphicsBuffer::
+bool CocoaGLGraphicsBuffer::
 begin_frame(FrameMode mode, Thread *current_thread) {
 begin_frame(FrameMode mode, Thread *current_thread) {
   if (_gsg == nullptr) {
   if (_gsg == nullptr) {
     return false;
     return false;
   }
   }
 
 
-  CocoaGraphicsStateGuardian *cocoagsg;
+  CocoaGLGraphicsStateGuardian *cocoagsg;
   DCAST_INTO_R(cocoagsg, _gsg, false);
   DCAST_INTO_R(cocoagsg, _gsg, false);
   nassertr(cocoagsg->_context != nil, false);
   nassertr(cocoagsg->_context != nil, false);
 
 
@@ -66,14 +66,14 @@ begin_frame(FrameMode mode, Thread *current_thread) {
  * completed for a given frame.  It should do whatever finalization is
  * completed for a given frame.  It should do whatever finalization is
  * required.
  * required.
  */
  */
-void CocoaGraphicsBuffer::
+void CocoaGLGraphicsBuffer::
 end_frame(FrameMode mode, Thread *current_thread) {
 end_frame(FrameMode mode, Thread *current_thread) {
   nassertv(_gsg != nullptr);
   nassertv(_gsg != nullptr);
 
 
   GLGraphicsBuffer::end_frame(mode, current_thread);
   GLGraphicsBuffer::end_frame(mode, current_thread);
 
 
   // Release the context.
   // Release the context.
-  CocoaGraphicsStateGuardian *cocoagsg;
+  CocoaGLGraphicsStateGuardian *cocoagsg;
   DCAST_INTO_V(cocoagsg, _gsg);
   DCAST_INTO_V(cocoagsg, _gsg);
   cocoagsg->unlock_context();
   cocoagsg->unlock_context();
 }
 }
@@ -82,16 +82,16 @@ end_frame(FrameMode mode, Thread *current_thread) {
  * Opens the buffer right now.  Called from the window thread.  Returns true
  * Opens the buffer right now.  Called from the window thread.  Returns true
  * if the buffer is successfully opened, or false if there was a problem.
  * if the buffer is successfully opened, or false if there was a problem.
  */
  */
-bool CocoaGraphicsBuffer::
+bool CocoaGLGraphicsBuffer::
 open_buffer() {
 open_buffer() {
   CocoaGraphicsPipe *cocoa_pipe;
   CocoaGraphicsPipe *cocoa_pipe;
   DCAST_INTO_R(cocoa_pipe, _pipe, false);
   DCAST_INTO_R(cocoa_pipe, _pipe, false);
 
 
   // GSG CreationInitialization
   // GSG CreationInitialization
-  CocoaGraphicsStateGuardian *cocoagsg;
+  CocoaGLGraphicsStateGuardian *cocoagsg;
   if (_gsg == nullptr) {
   if (_gsg == nullptr) {
     // There is no old gsg.  Create a new one.
     // There is no old gsg.  Create a new one.
-    cocoagsg = new CocoaGraphicsStateGuardian(_engine, _pipe, nullptr);
+    cocoagsg = new CocoaGLGraphicsStateGuardian(_engine, _pipe, nullptr);
     cocoagsg->choose_pixel_format(_fb_properties, cocoa_pipe->get_display_id(), false);
     cocoagsg->choose_pixel_format(_fb_properties, cocoa_pipe->get_display_id(), false);
     _gsg = cocoagsg;
     _gsg = cocoagsg;
   } else {
   } else {
@@ -99,7 +99,7 @@ open_buffer() {
     // with the old gsg.
     // with the old gsg.
     DCAST_INTO_R(cocoagsg, _gsg, false);
     DCAST_INTO_R(cocoagsg, _gsg, false);
     if (!cocoagsg->get_fb_properties().subsumes(_fb_properties)) {
     if (!cocoagsg->get_fb_properties().subsumes(_fb_properties)) {
-      cocoagsg = new CocoaGraphicsStateGuardian(_engine, _pipe, cocoagsg);
+      cocoagsg = new CocoaGLGraphicsStateGuardian(_engine, _pipe, cocoagsg);
       cocoagsg->choose_pixel_format(_fb_properties, cocoa_pipe->get_display_id(), false);
       cocoagsg->choose_pixel_format(_fb_properties, cocoa_pipe->get_display_id(), false);
       _gsg = cocoagsg;
       _gsg = cocoagsg;
     }
     }
@@ -153,11 +153,11 @@ open_buffer() {
 /**
 /**
  * Closes the buffer right now.  Called from the window thread.
  * Closes the buffer right now.  Called from the window thread.
  */
  */
-void CocoaGraphicsBuffer::
+void CocoaGLGraphicsBuffer::
 close_buffer() {
 close_buffer() {
   if (_gsg != nullptr) {
   if (_gsg != nullptr) {
-    CocoaGraphicsStateGuardian *cocoagsg;
-    cocoagsg = DCAST(CocoaGraphicsStateGuardian, _gsg);
+    CocoaGLGraphicsStateGuardian *cocoagsg;
+    cocoagsg = DCAST(CocoaGLGraphicsStateGuardian, _gsg);
 
 
     if (cocoagsg != nullptr && cocoagsg->_context != nil) {
     if (cocoagsg != nullptr && cocoagsg->_context != nil) {
       cocoagsg->lock_context();
       cocoagsg->lock_context();

+ 12 - 0
panda/src/cocoagldisplay/cocoaGLGraphicsPipe.I

@@ -0,0 +1,12 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file cocoaGLGraphicsPipe.I
+ * @author rdb
+ * @date 2023-03-20
+ */

+ 65 - 0
panda/src/cocoagldisplay/cocoaGLGraphicsPipe.h

@@ -0,0 +1,65 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file cocoaGLGraphicsPipe.h
+ * @author rdb
+ * @date 2023-03-20
+ */
+
+#ifndef COCOAGLGRAPHICSPIPE_H
+#define COCOAGLGRAPHICSPIPE_H
+
+#include "cocoaGraphicsPipe.h"
+
+class FrameBufferProperties;
+
+/**
+ * This graphics pipe represents the interface for creating OpenGL graphics
+ * windows on a Cocoa-based (e.g.  Mac OS X) client.
+ */
+class EXPCL_PANDA_COCOAGLDISPLAY CocoaGLGraphicsPipe : public CocoaGraphicsPipe {
+public:
+  CocoaGLGraphicsPipe(CGDirectDisplayID display = CGMainDisplayID());
+  virtual ~CocoaGLGraphicsPipe();
+
+  virtual std::string get_interface_name() const;
+  static PT(GraphicsPipe) pipe_constructor();
+
+protected:
+  virtual PT(GraphicsOutput) make_output(const std::string &name,
+                                         const FrameBufferProperties &fb_prop,
+                                         const WindowProperties &win_prop,
+                                         int flags,
+                                         GraphicsEngine *engine,
+                                         GraphicsStateGuardian *gsg,
+                                         GraphicsOutput *host,
+                                         int retry,
+                                         bool &precertify);
+  virtual PT(GraphicsStateGuardian) make_callback_gsg(GraphicsEngine *engine);
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    CocoaGraphicsPipe::init_type();
+    register_type(_type_handle, "CocoaGLGraphicsPipe",
+                  CocoaGraphicsPipe::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "cocoaGLGraphicsPipe.I"
+
+#endif

+ 150 - 0
panda/src/cocoagldisplay/cocoaGLGraphicsPipe.mm

@@ -0,0 +1,150 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file cocoaGLGraphicsPipe.mm
+ * @author rdb
+ * @date 2023-03-20
+ */
+
+#include "cocoaGLGraphicsPipe.h"
+#include "cocoaGLGraphicsBuffer.h"
+#include "cocoaGLGraphicsWindow.h"
+#include "cocoaGLGraphicsStateGuardian.h"
+#include "config_cocoagldisplay.h"
+#include "frameBufferProperties.h"
+
+TypeHandle CocoaGLGraphicsPipe::_type_handle;
+
+/**
+ * Takes a CoreGraphics display ID, which defaults to the main display.
+ */
+CocoaGLGraphicsPipe::
+CocoaGLGraphicsPipe(CGDirectDisplayID display) : CocoaGraphicsPipe(display) {
+  _supported_types = OT_window | OT_buffer | OT_texture_buffer;
+  _is_valid = true;
+}
+
+/**
+ *
+ */
+CocoaGLGraphicsPipe::
+~CocoaGLGraphicsPipe() {
+}
+
+/**
+ * Returns the name of the rendering interface associated with this
+ * GraphicsPipe.  This is used to present to the user to allow him/her to
+ * choose between several possible GraphicsPipes available on a particular
+ * platform, so the name should be meaningful and unique for a given platform.
+ */
+std::string CocoaGLGraphicsPipe::
+get_interface_name() const {
+  return "OpenGL";
+}
+
+/**
+ * This function is passed to the GraphicsPipeSelection object to allow the
+ * user to make a default CocoaGLGraphicsPipe.
+ */
+PT(GraphicsPipe) CocoaGLGraphicsPipe::
+pipe_constructor() {
+  return new CocoaGLGraphicsPipe;
+}
+
+/**
+ * Creates a new window on the pipe, if possible.
+ */
+PT(GraphicsOutput) CocoaGLGraphicsPipe::
+make_output(const std::string &name,
+            const FrameBufferProperties &fb_prop,
+            const WindowProperties &win_prop,
+            int flags,
+            GraphicsEngine *engine,
+            GraphicsStateGuardian *gsg,
+            GraphicsOutput *host,
+            int retry,
+            bool &precertify) {
+
+  if (!_is_valid) {
+    return nullptr;
+  }
+
+  CocoaGLGraphicsStateGuardian *cocoagsg = nullptr;
+  if (gsg != nullptr) {
+    DCAST_INTO_R(cocoagsg, gsg, nullptr);
+  }
+
+  // First thing to try: a CocoaGLGraphicsWindow
+
+  if (retry == 0) {
+    if ((flags & BF_require_parasite) != 0 ||
+        (flags & BF_refuse_window) != 0 ||
+        (flags & BF_resizeable) != 0 ||
+        (flags & BF_size_track_host) != 0 ||
+        (flags & BF_rtt_cumulative) != 0 ||
+        (flags & BF_can_bind_color) != 0 ||
+        (flags & BF_can_bind_every) != 0 ||
+        (flags & BF_can_bind_layered) != 0) {
+      return nullptr;
+    }
+    return new CocoaGLGraphicsWindow(engine, this, name, fb_prop, win_prop,
+                                     flags, gsg, host);
+  }
+
+  // Second thing to try: a GLGraphicsBuffer.  This requires a context, so if
+  // we don't have a host window, we instead create a CocoaGLGraphicsBuffer,
+  // which wraps around GLGraphicsBuffer and manages a context.
+
+  if (retry == 1) {
+    if (!gl_support_fbo ||
+        (flags & (BF_require_parasite | BF_require_window)) != 0) {
+      return nullptr;
+    }
+    // Early failure - if we are sure that this buffer WONT meet specs, we can
+    // bail out early.
+    if ((flags & BF_fb_props_optional) == 0) {
+      if (fb_prop.get_indexed_color() ||
+          fb_prop.get_back_buffers() > 0 ||
+          fb_prop.get_accum_bits() > 0) {
+        return nullptr;
+      }
+    }
+    if (cocoagsg != nullptr && cocoagsg->is_valid() && !cocoagsg->needs_reset()) {
+      if (!cocoagsg->_supports_framebuffer_object ||
+          cocoagsg->_glDrawBuffers == nullptr) {
+        return nullptr;
+      }
+      else if (fb_prop.is_basic()) {
+        // Early success - if we are sure that this buffer WILL meet specs, we
+        // can precertify it.
+        precertify = true;
+      }
+    }
+    if (host != nullptr) {
+      return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
+                                  flags, gsg, host);
+    } else {
+      return new CocoaGLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
+                                       flags, gsg, host);
+    }
+  }
+
+  // Nothing else left to try.
+  return nullptr;
+}
+
+/**
+ * This is called when make_output() is used to create a
+ * CallbackGraphicsWindow.  If the GraphicsPipe can construct a GSG that's not
+ * associated with any particular window object, do so now, assuming the
+ * correct graphics context has been set up externally.
+ */
+PT(GraphicsStateGuardian) CocoaGLGraphicsPipe::
+make_callback_gsg(GraphicsEngine *engine) {
+  return new CocoaGLGraphicsStateGuardian(engine, this, nullptr);
+}

+ 4 - 4
panda/src/cocoadisplay/cocoaGraphicsStateGuardian.I → panda/src/cocoagldisplay/cocoaGLGraphicsStateGuardian.I

@@ -6,7 +6,7 @@
  * license.  You should have received a copy of this license along
  * license.  You should have received a copy of this license along
  * with this source code in a file named "LICENSE."
  * with this source code in a file named "LICENSE."
  *
  *
- * @file cocoaGraphicsStateGuardian.I
+ * @file cocoaGLGraphicsStateGuardian.I
  * @author rdb
  * @author rdb
  * @date 2012-05-14
  * @date 2012-05-14
  */
  */
@@ -15,7 +15,7 @@
  * Gets the FrameBufferProperties for all windows and buffers that use this
  * Gets the FrameBufferProperties for all windows and buffers that use this
  * GSG.
  * GSG.
  */
  */
-INLINE const FrameBufferProperties &CocoaGraphicsStateGuardian::
+INLINE const FrameBufferProperties &CocoaGLGraphicsStateGuardian::
 get_fb_properties() const {
 get_fb_properties() const {
   return _fbprops;
   return _fbprops;
 }
 }
@@ -23,7 +23,7 @@ get_fb_properties() const {
 /**
 /**
  * Locks the context.
  * Locks the context.
  */
  */
-INLINE void CocoaGraphicsStateGuardian::
+INLINE void CocoaGLGraphicsStateGuardian::
 lock_context() {
 lock_context() {
   nassertv(_context != nil);
   nassertv(_context != nil);
   CGLLockContext((CGLContextObj) [_context CGLContextObj]);
   CGLLockContext((CGLContextObj) [_context CGLContextObj]);
@@ -32,7 +32,7 @@ lock_context() {
 /**
 /**
  * Unlocks the context.
  * Unlocks the context.
  */
  */
-INLINE void CocoaGraphicsStateGuardian::
+INLINE void CocoaGLGraphicsStateGuardian::
 unlock_context() {
 unlock_context() {
   nassertv(_context != nil);
   nassertv(_context != nil);
   CGLUnlockContext((CGLContextObj) [_context CGLContextObj]);
   CGLUnlockContext((CGLContextObj) [_context CGLContextObj]);

+ 9 - 9
panda/src/cocoadisplay/cocoaGraphicsStateGuardian.h → panda/src/cocoagldisplay/cocoaGLGraphicsStateGuardian.h

@@ -6,13 +6,13 @@
  * license.  You should have received a copy of this license along
  * license.  You should have received a copy of this license along
  * with this source code in a file named "LICENSE."
  * with this source code in a file named "LICENSE."
  *
  *
- * @file cocoaGraphicsStateGuardian.h
+ * @file cocoaGLGraphicsStateGuardian.h
  * @author rdb
  * @author rdb
  * @date 2012-05-14
  * @date 2012-05-14
  */
  */
 
 
-#ifndef COCOAGRAPHICSSTATEGUARDIAN_H
-#define COCOAGRAPHICSSTATEGUARDIAN_H
+#ifndef COCOAGLGRAPHICSSTATEGUARDIAN_H
+#define COCOAGLGRAPHICSSTATEGUARDIAN_H
 
 
 #include "pandabase.h"
 #include "pandabase.h"
 #include "cocoaGraphicsPipe.h"
 #include "cocoaGraphicsPipe.h"
@@ -26,7 +26,7 @@
  * A tiny specialization on GLGraphicsStateGuardian to add some Cocoa-specific
  * A tiny specialization on GLGraphicsStateGuardian to add some Cocoa-specific
  * information.
  * information.
  */
  */
-class EXPCL_PANDA_COCOADISPLAY CocoaGraphicsStateGuardian : public GLGraphicsStateGuardian {
+class EXPCL_PANDA_COCOAGLDISPLAY CocoaGLGraphicsStateGuardian : public GLGraphicsStateGuardian {
 public:
 public:
   INLINE const FrameBufferProperties &get_fb_properties() const;
   INLINE const FrameBufferProperties &get_fb_properties() const;
   void get_properties(FrameBufferProperties &properties,
   void get_properties(FrameBufferProperties &properties,
@@ -35,10 +35,10 @@ public:
                            CGDirectDisplayID display,
                            CGDirectDisplayID display,
                            bool need_pbuffer);
                            bool need_pbuffer);
 
 
-  CocoaGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
-                             CocoaGraphicsStateGuardian *share_with);
+  CocoaGLGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
+                               CocoaGLGraphicsStateGuardian *share_with);
 
 
-  virtual ~CocoaGraphicsStateGuardian();
+  virtual ~CocoaGLGraphicsStateGuardian();
   bool setup_vsync();
   bool setup_vsync();
 
 
   INLINE void lock_context();
   INLINE void lock_context();
@@ -64,7 +64,7 @@ public:
   }
   }
   static void init_type() {
   static void init_type() {
     GLGraphicsStateGuardian::init_type();
     GLGraphicsStateGuardian::init_type();
-    register_type(_type_handle, "CocoaGraphicsStateGuardian",
+    register_type(_type_handle, "CocoaGLGraphicsStateGuardian",
                   GLGraphicsStateGuardian::get_class_type());
                   GLGraphicsStateGuardian::get_class_type());
   }
   }
   virtual TypeHandle get_type() const {
   virtual TypeHandle get_type() const {
@@ -76,6 +76,6 @@ private:
   static TypeHandle _type_handle;
   static TypeHandle _type_handle;
 };
 };
 
 
-#include "cocoaGraphicsStateGuardian.I"
+#include "cocoaGLGraphicsStateGuardian.I"
 
 
 #endif
 #endif

+ 16 - 16
panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm → panda/src/cocoagldisplay/cocoaGLGraphicsStateGuardian.mm

@@ -6,12 +6,12 @@
  * license.  You should have received a copy of this license along
  * license.  You should have received a copy of this license along
  * with this source code in a file named "LICENSE."
  * with this source code in a file named "LICENSE."
  *
  *
- * @file cocoaGraphicsStateGuardian.mm
+ * @file cocoaGLGraphicsStateGuardian.mm
  * @author rdb
  * @author rdb
  * @date 2012-05-14
  * @date 2012-05-14
  */
  */
 
 
-#include "cocoaGraphicsStateGuardian.h"
+#include "cocoaGLGraphicsStateGuardian.h"
 #include "config_cocoadisplay.h"
 #include "config_cocoadisplay.h"
 #include "lightReMutexHolder.h"
 #include "lightReMutexHolder.h"
 
 
@@ -30,34 +30,34 @@
 
 
 /**
 /**
  * Called whenever a display wants a frame.  The context argument contains the
  * Called whenever a display wants a frame.  The context argument contains the
- * applicable CocoaGraphicsStateGuardian.
+ * applicable CocoaGLGraphicsStateGuardian.
  */
  */
 static CVReturn
 static CVReturn
 display_link_cb(CVDisplayLinkRef link, const CVTimeStamp *now,
 display_link_cb(CVDisplayLinkRef link, const CVTimeStamp *now,
                 const CVTimeStamp* output_time, CVOptionFlags flags_in,
                 const CVTimeStamp* output_time, CVOptionFlags flags_in,
                 CVOptionFlags *flags_out, void *context) {
                 CVOptionFlags *flags_out, void *context) {
-  CocoaGraphicsStateGuardian *gsg = (CocoaGraphicsStateGuardian *)context;
+  CocoaGLGraphicsStateGuardian *gsg = (CocoaGLGraphicsStateGuardian *)context;
   gsg->_swap_lock.lock();
   gsg->_swap_lock.lock();
   gsg->_swap_condition.notify();
   gsg->_swap_condition.notify();
   gsg->_swap_lock.unlock();
   gsg->_swap_lock.unlock();
   return kCVReturnSuccess;
   return kCVReturnSuccess;
 }
 }
 
 
-TypeHandle CocoaGraphicsStateGuardian::_type_handle;
+TypeHandle CocoaGLGraphicsStateGuardian::_type_handle;
 
 
 /**
 /**
  *
  *
  */
  */
-CocoaGraphicsStateGuardian::
-CocoaGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
-                           CocoaGraphicsStateGuardian *share_with) :
+CocoaGLGraphicsStateGuardian::
+CocoaGLGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
+                           CocoaGLGraphicsStateGuardian *share_with) :
   GLGraphicsStateGuardian(engine, pipe),
   GLGraphicsStateGuardian(engine, pipe),
   _swap_condition(_swap_lock)
   _swap_condition(_swap_lock)
 {
 {
   _share_context = nil;
   _share_context = nil;
   _context = nil;
   _context = nil;
 
 
-  if (share_with != (CocoaGraphicsStateGuardian *)NULL) {
+  if (share_with != (CocoaGLGraphicsStateGuardian *)NULL) {
     _prepared_objects = share_with->get_prepared_objects();
     _prepared_objects = share_with->get_prepared_objects();
     _share_context = share_with->_context;
     _share_context = share_with->_context;
   }
   }
@@ -66,8 +66,8 @@ CocoaGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
 /**
 /**
  *
  *
  */
  */
-CocoaGraphicsStateGuardian::
-~CocoaGraphicsStateGuardian() {
+CocoaGLGraphicsStateGuardian::
+~CocoaGLGraphicsStateGuardian() {
   if (_format != nil) {
   if (_format != nil) {
     [_format release];
     [_format release];
   }
   }
@@ -88,7 +88,7 @@ CocoaGraphicsStateGuardian::
  * Creates a CVDisplayLink, which tells us when the display the window is on
  * Creates a CVDisplayLink, which tells us when the display the window is on
  * will want a frame.
  * will want a frame.
  */
  */
-bool CocoaGraphicsStateGuardian::
+bool CocoaGLGraphicsStateGuardian::
 setup_vsync() {
 setup_vsync() {
   if (_display_link != nil) {
   if (_display_link != nil) {
     // Already set up.
     // Already set up.
@@ -125,7 +125,7 @@ setup_vsync() {
 /**
 /**
  * Gets the FrameBufferProperties to match the indicated config.
  * Gets the FrameBufferProperties to match the indicated config.
  */
  */
-void CocoaGraphicsStateGuardian::
+void CocoaGLGraphicsStateGuardian::
 get_properties(FrameBufferProperties &properties, NSOpenGLPixelFormat* pixel_format, int screen) {
 get_properties(FrameBufferProperties &properties, NSOpenGLPixelFormat* pixel_format, int screen) {
 
 
   properties.clear();
   properties.clear();
@@ -210,7 +210,7 @@ get_properties(FrameBufferProperties &properties, NSOpenGLPixelFormat* pixel_for
  * Selects a visual or fbconfig for all the windows and buffers that use this
  * Selects a visual or fbconfig for all the windows and buffers that use this
  * gsg.  Also creates the GL context and obtains the visual.
  * gsg.  Also creates the GL context and obtains the visual.
  */
  */
-void CocoaGraphicsStateGuardian::
+void CocoaGLGraphicsStateGuardian::
 choose_pixel_format(const FrameBufferProperties &properties,
 choose_pixel_format(const FrameBufferProperties &properties,
                     CGDirectDisplayID display,
                     CGDirectDisplayID display,
                     bool need_pbuffer) {
                     bool need_pbuffer) {
@@ -357,7 +357,7 @@ choose_pixel_format(const FrameBufferProperties &properties,
 /**
 /**
  * Queries the runtime version of OpenGL in use.
  * Queries the runtime version of OpenGL in use.
  */
  */
-void CocoaGraphicsStateGuardian::
+void CocoaGLGraphicsStateGuardian::
 query_gl_version() {
 query_gl_version() {
   GLGraphicsStateGuardian::query_gl_version();
   GLGraphicsStateGuardian::query_gl_version();
 
 
@@ -381,7 +381,7 @@ query_gl_version() {
  * extension is defined in the OpenGL runtime prior to calling this; it is an
  * extension is defined in the OpenGL runtime prior to calling this; it is an
  * error to call this for a function that is not defined.
  * error to call this for a function that is not defined.
  */
  */
-void *CocoaGraphicsStateGuardian::
+void *CocoaGLGraphicsStateGuardian::
 do_get_extension_func(const char *name) {
 do_get_extension_func(const char *name) {
   char* fullname = (char*) malloc(strlen(name) + 2);
   char* fullname = (char*) malloc(strlen(name) + 2);
   strcpy(fullname + 1, name);
   strcpy(fullname + 1, name);

+ 12 - 0
panda/src/cocoagldisplay/cocoaGLGraphicsWindow.I

@@ -0,0 +1,12 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file cocoaGLGraphicsWindow.I
+ * @author rdb
+ * @date 2023-03-18
+ */

+ 66 - 0
panda/src/cocoagldisplay/cocoaGLGraphicsWindow.h

@@ -0,0 +1,66 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file cocoaGLGraphicsWindow.h
+ * @author rdb
+ * @date 2023-03-18
+ */
+
+#ifndef COCOAGLGRAPHICSWINDOW_H
+#define COCOAGLGRAPHICSWINDOW_H
+
+#include "cocoaGraphicsWindow.h"
+
+/**
+ *
+ */
+class EXPCL_PANDA_COCOADISPLAY CocoaGLGraphicsWindow : public CocoaGraphicsWindow {
+public:
+  CocoaGLGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
+                        const std::string &name,
+                        const FrameBufferProperties &fb_prop,
+                        const WindowProperties &win_prop,
+                        int flags,
+                        GraphicsStateGuardian *gsg,
+                        GraphicsOutput *host);
+  virtual ~CocoaGLGraphicsWindow();
+
+  virtual bool begin_frame(FrameMode mode, Thread *current_thread);
+  virtual void end_frame(FrameMode mode, Thread *current_thread);
+  virtual void end_flip();
+
+  virtual void update_context();
+  virtual void unbind_context();
+
+protected:
+  virtual bool open_window();
+
+private:
+  bool _vsync_enabled = false;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    CocoaGraphicsWindow::init_type();
+    register_type(_type_handle, "CocoaGLGraphicsWindow",
+                  CocoaGraphicsWindow::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "cocoaGLGraphicsWindow.I"
+
+#endif

+ 274 - 0
panda/src/cocoagldisplay/cocoaGLGraphicsWindow.mm

@@ -0,0 +1,274 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file cocoaGLGraphicsWindow.mm
+ * @author rdb
+ * @date 2023-03-18
+ */
+
+#include "cocoaGLGraphicsWindow.h"
+#include "cocoaGLGraphicsStateGuardian.h"
+#include "config_cocoadisplay.h"
+
+#import <OpenGL/OpenGL.h>
+
+TypeHandle CocoaGLGraphicsWindow::_type_handle;
+
+/**
+ *
+ */
+CocoaGLGraphicsWindow::
+CocoaGLGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
+                      const std::string &name,
+                      const FrameBufferProperties &fb_prop,
+                      const WindowProperties &win_prop,
+                      int flags,
+                      GraphicsStateGuardian *gsg,
+                      GraphicsOutput *host) :
+  CocoaGraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
+{
+}
+
+/**
+ *
+ */
+CocoaGLGraphicsWindow::
+~CocoaGLGraphicsWindow() {
+}
+
+/**
+ * This function will be called within the draw thread before beginning
+ * rendering for a given frame.  It should do whatever setup is required, and
+ * return true if the frame should be rendered, or false if it should be
+ * skipped.
+ */
+bool CocoaGLGraphicsWindow::
+begin_frame(FrameMode mode, Thread *current_thread) {
+  PStatTimer timer(_make_current_pcollector, current_thread);
+
+  begin_frame_spam(mode);
+  if (_gsg == nullptr) {
+    return false;
+  }
+
+  CocoaGLGraphicsStateGuardian *cocoagsg;
+  DCAST_INTO_R(cocoagsg, _gsg, false);
+  nassertr(cocoagsg->_context != nil, false);
+  nassertr(_view != nil, false);
+
+  // Place a lock on the context.
+  cocoagsg->lock_context();
+
+  // Set the drawable.
+  // Although not recommended, it is technically possible to use the same
+  // context with multiple different-sized windows.  If that happens, the
+  // context needs to be updated accordingly.
+  if ([cocoagsg->_context view] != _view) {
+    // XXX I'm not 100% sure that changing the view requires it to update.
+    _context_needs_update = true;
+    [cocoagsg->_context setView:_view];
+
+    if (cocoadisplay_cat.is_spam()) {
+      cocoadisplay_cat.spam()
+        << "Switching context to view " << _view << "\n";
+    }
+  }
+
+  // Update the context if necessary, to make it reallocate buffers etc.
+  if (_context_needs_update) {
+    if ([NSThread isMainThread]) {
+      [cocoagsg->_context update];
+      _context_needs_update = false;
+    } else {
+      cocoagsg->unlock_context();
+      return false;
+    }
+  }
+
+  // Lock the view for drawing.
+  if (!_properties.get_fullscreen()) {
+    nassertr_always([_view lockFocusIfCanDraw], false);
+  }
+
+  // Make the context current.
+  [cocoagsg->_context makeCurrentContext];
+
+  // Now that we have made the context current to a window, we can reset the
+  // GSG state if this is the first time it has been used.  (We can't just
+  // call reset() when we construct the GSG, because reset() requires having a
+  // current context.)
+  cocoagsg->reset_if_new();
+
+  if (mode == FM_render) {
+    // begin_render_texture();
+    clear_cube_map_selection();
+  }
+
+  _gsg->set_current_properties(&get_fb_properties());
+  return _gsg->begin_frame(current_thread);
+}
+
+/**
+ * This function will be called within the draw thread after rendering is
+ * completed for a given frame.  It should do whatever finalization is
+ * required.
+ */
+void CocoaGLGraphicsWindow::
+end_frame(FrameMode mode, Thread *current_thread) {
+  end_frame_spam(mode);
+  nassertv(_gsg != (GraphicsStateGuardian *)NULL);
+
+  if (!_properties.get_fullscreen()) {
+    [_view unlockFocus];
+  }
+  // Release the context.
+  CocoaGLGraphicsStateGuardian *cocoagsg;
+  DCAST_INTO_V(cocoagsg, _gsg);
+
+  cocoagsg->unlock_context();
+
+  if (mode == FM_render) {
+    // end_render_texture();
+    copy_to_textures();
+  }
+
+  _gsg->end_frame(current_thread);
+
+  if (mode == FM_render) {
+    trigger_flip();
+    clear_cube_map_selection();
+  }
+}
+
+/**
+ * This function will be called within the draw thread after begin_flip() has
+ * been called on all windows, to finish the exchange of the front and back
+ * buffers.
+ *
+ * This should cause the window to wait for the flip, if necessary.
+ */
+void CocoaGLGraphicsWindow::
+end_flip() {
+  if (_gsg != nullptr && _flip_ready) {
+
+    CocoaGLGraphicsStateGuardian *cocoagsg;
+    DCAST_INTO_V(cocoagsg, _gsg);
+
+    if (_vsync_enabled) {
+      AtomicAdjust::Integer cur_frame = ClockObject::get_global_clock()->get_frame_count();
+      if (AtomicAdjust::set(cocoagsg->_last_wait_frame, cur_frame) != cur_frame) {
+        cocoagsg->_swap_lock.lock();
+        cocoagsg->_swap_condition.wait();
+        cocoagsg->_swap_lock.unlock();
+      }
+    }
+
+    cocoagsg->lock_context();
+
+    // Swap the front and back buffer.
+    [cocoagsg->_context flushBuffer];
+
+    [[_view window] flushWindow];
+
+    cocoagsg->unlock_context();
+  }
+  GraphicsWindow::end_flip();
+}
+
+/**
+ * Opens the window right now.  Called from the window thread.  Returns true
+ * if the window is successfully opened, or false if there was a problem.
+ */
+bool CocoaGLGraphicsWindow::
+open_window() {
+  // GSG CreationInitialization
+  CocoaGLGraphicsStateGuardian *cocoagsg;
+  if (_gsg == nullptr) {
+    // There is no old gsg.  Create a new one.
+    cocoagsg = new CocoaGLGraphicsStateGuardian(_engine, _pipe, nullptr);
+    cocoagsg->choose_pixel_format(_fb_properties, _display, false);
+    _gsg = cocoagsg;
+  } else {
+    // If the old gsg has the wrong pixel format, create a new one that shares
+    // with the old gsg.
+    DCAST_INTO_R(cocoagsg, _gsg, false);
+    if (!cocoagsg->get_fb_properties().subsumes(_fb_properties)) {
+      cocoagsg = new CocoaGLGraphicsStateGuardian(_engine, _pipe, cocoagsg);
+      cocoagsg->choose_pixel_format(_fb_properties, _display, false);
+      _gsg = cocoagsg;
+    }
+  }
+
+  if (cocoagsg->_context == nil) {
+    // Could not obtain a proper context.
+    _gsg.clear();
+    close_window();
+    return false;
+  }
+
+  if (!CocoaGraphicsWindow::open_window()) {
+    return false;
+  }
+
+  // Make the context current.
+  cocoagsg->lock_context();
+  _context_needs_update = false;
+  [cocoagsg->_context makeCurrentContext];
+  [cocoagsg->_context setView:_view];
+  [cocoagsg->_context update];
+
+  cocoagsg->reset_if_new();
+  cocoagsg->unlock_context();
+
+  if (!cocoagsg->is_valid()) {
+    close_window();
+    return false;
+  }
+
+  if (!cocoagsg->get_fb_properties().verify_hardware_software
+      (_fb_properties, cocoagsg->get_gl_renderer())) {
+    close_window();
+    return false;
+  }
+  _fb_properties = cocoagsg->get_fb_properties();
+
+  _vsync_enabled = sync_video && cocoagsg->setup_vsync();
+
+  return true;
+}
+
+/**
+ * Updates the context.
+ */
+void CocoaGLGraphicsWindow::
+update_context() {
+  CocoaGLGraphicsStateGuardian *cocoagsg;
+  cocoagsg = DCAST(CocoaGLGraphicsStateGuardian, _gsg);
+
+  if (cocoagsg != nullptr && cocoagsg->_context != nil) {
+    cocoagsg->lock_context();
+    _context_needs_update = false;
+    [cocoagsg->_context update];
+    cocoagsg->unlock_context();
+  }
+}
+
+/**
+ * Unbinds the context from the window.
+ */
+void CocoaGLGraphicsWindow::
+unbind_context() {
+  CocoaGLGraphicsStateGuardian *cocoagsg;
+  cocoagsg = DCAST(CocoaGLGraphicsStateGuardian, _gsg);
+
+  if (cocoagsg != nullptr && cocoagsg->_context != nil) {
+    cocoagsg->lock_context();
+    [cocoagsg->_context clearDrawable];
+    cocoagsg->unlock_context();
+  }
+}

+ 21 - 0
panda/src/cocoagldisplay/config_cocoagldisplay.h

@@ -0,0 +1,21 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file config_cocoagldisplay.h
+ * @author rdb
+ * @date 2023-03-20
+ */
+
+#ifndef CONFIG_COCOAGLDISPLAY_H
+#define CONFIG_COCOAGLDISPLAY_H
+
+#include "config_cocoadisplay.h"
+
+extern EXPCL_PANDA_COCOAGLDISPLAY void init_libcocoagldisplay();
+
+#endif

+ 60 - 0
panda/src/cocoagldisplay/config_cocoagldisplay.mm

@@ -0,0 +1,60 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file config_cocoagldisplay.mm
+ * @author rdb
+ * @date 2023-03-20
+ */
+
+#include "config_cocoagldisplay.h"
+#include "cocoaGLGraphicsBuffer.h"
+#include "cocoaGLGraphicsPipe.h"
+#include "cocoaGLGraphicsStateGuardian.h"
+#include "cocoaGLGraphicsWindow.h"
+#include "graphicsPipeSelection.h"
+#include "dconfig.h"
+#include "pandaSystem.h"
+
+#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_PANDA_COCOAGLDISPLAY)
+  #error Buildsystem error: BUILDING_PANDA_COCOAGLDISPLAY not defined
+#endif
+
+Configure(config_cocoagldisplay);
+
+ConfigureFn(config_cocoagldisplay) {
+  init_libcocoagldisplay();
+}
+
+/**
+ * Initializes the library.  This must be called at least once before any of
+ * the functions or classes in this library can be used.  Normally it will be
+ * called by the static initializers and need not be called explicitly, but
+ * special cases exist.
+ */
+void
+init_libcocoagldisplay() {
+  static bool initialized = false;
+  if (initialized) {
+    return;
+  }
+  initialized = true;
+
+  init_libcocoadisplay();
+
+  CocoaGLGraphicsBuffer::init_type();
+  CocoaGLGraphicsPipe::init_type();
+  CocoaGLGraphicsStateGuardian::init_type();
+  CocoaGLGraphicsWindow::init_type();
+
+  GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr();
+  selection->add_pipe_type(CocoaGLGraphicsPipe::get_class_type(),
+                           CocoaGLGraphicsPipe::pipe_constructor);
+
+  PandaSystem *ps = PandaSystem::get_global_ptr();
+  ps->set_system_tag("OpenGL", "window_system", "Cocoa");
+}

+ 5 - 0
panda/src/cocoagldisplay/p3cocoagldisplay_composite1.mm

@@ -0,0 +1,5 @@
+#include "cocoaGLGraphicsBuffer.mm"
+#include "cocoaGLGraphicsPipe.mm"
+#include "cocoaGLGraphicsStateGuardian.mm"
+#include "cocoaGLGraphicsWindow.mm"
+#include "config_cocoagldisplay.mm"

+ 9 - 0
panda/src/pandabase/pandasymbols.h

@@ -111,6 +111,7 @@
 /* BUILDING_PANDAGL for these: */
 /* BUILDING_PANDAGL for these: */
 #ifdef BUILDING_PANDAGL
 #ifdef BUILDING_PANDAGL
   #define BUILDING_PANDA_COCOADISPLAY
   #define BUILDING_PANDA_COCOADISPLAY
+  #define BUILDING_PANDA_COCOAGLDISPLAY
   #define BUILDING_PANDA_GLGSG
   #define BUILDING_PANDA_GLGSG
   #define BUILDING_PANDA_GLXDISPLAY
   #define BUILDING_PANDA_GLXDISPLAY
   #define BUILDING_PANDA_WGLDISPLAY
   #define BUILDING_PANDA_WGLDISPLAY
@@ -162,6 +163,14 @@
   #define EXPTP_PANDA_COCOADISPLAY IMPORT_TEMPL
   #define EXPTP_PANDA_COCOADISPLAY IMPORT_TEMPL
 #endif
 #endif
 
 
+#ifdef BUILDING_PANDA_COCOAGLDISPLAY
+  #define EXPCL_PANDA_COCOAGLDISPLAY EXPORT_CLASS
+  #define EXPTP_PANDA_COCOAGLDISPLAY EXPORT_TEMPL
+#else
+  #define EXPCL_PANDA_COCOAGLDISPLAY IMPORT_CLASS
+  #define EXPTP_PANDA_COCOAGLDISPLAY IMPORT_TEMPL
+#endif
+
 #ifdef BUILDING_PANDA_COLLIDE
 #ifdef BUILDING_PANDA_COLLIDE
   #define EXPCL_PANDA_COLLIDE EXPORT_CLASS
   #define EXPCL_PANDA_COLLIDE EXPORT_CLASS
   #define EXPTP_PANDA_COLLIDE EXPORT_TEMPL
   #define EXPTP_PANDA_COLLIDE EXPORT_TEMPL