The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
6.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. class OpenGLContext::NativeContext
  18. {
  19. public:
  20. NativeContext (Component& component,
  21. const OpenGLPixelFormat& pixFormat,
  22. void* contextToShare)
  23. {
  24. NSOpenGLPixelFormatAttribute attribs[] =
  25. {
  26. NSOpenGLPFADoubleBuffer,
  27. NSOpenGLPFAMPSafe,
  28. NSOpenGLPFAClosestPolicy,
  29. NSOpenGLPFANoRecovery,
  30. NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute) (pixFormat.redBits + pixFormat.greenBits + pixFormat.blueBits),
  31. NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute) pixFormat.alphaBits,
  32. NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute) pixFormat.depthBufferBits,
  33. NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute) pixFormat.stencilBufferBits,
  34. NSOpenGLPFAAccumSize, (NSOpenGLPixelFormatAttribute) (pixFormat.accumulationBufferRedBits + pixFormat.accumulationBufferGreenBits
  35. + pixFormat.accumulationBufferBlueBits + pixFormat.accumulationBufferAlphaBits),
  36. pixFormat.multisamplingLevel > 0 ? NSOpenGLPFASamples : (NSOpenGLPixelFormatAttribute) 0,
  37. (NSOpenGLPixelFormatAttribute) pixFormat.multisamplingLevel,
  38. 0
  39. };
  40. NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes: attribs];
  41. static MouseForwardingNSOpenGLViewClass cls;
  42. view = [cls.createInstance() initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
  43. pixelFormat: format];
  44. #if defined (MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
  45. if ([view respondsToSelector: @selector (setWantsBestResolutionOpenGLSurface:)])
  46. [view setWantsBestResolutionOpenGLSurface: YES];
  47. #endif
  48. [[NSNotificationCenter defaultCenter] addObserver: view
  49. selector: @selector (_surfaceNeedsUpdate:)
  50. name: NSViewGlobalFrameDidChangeNotification
  51. object: view];
  52. renderContext = [[[NSOpenGLContext alloc] initWithFormat: format
  53. shareContext: (NSOpenGLContext*) contextToShare] autorelease];
  54. [view setOpenGLContext: renderContext];
  55. [format release];
  56. viewAttachment = NSViewComponent::attachViewToComponent (component, view);
  57. }
  58. ~NativeContext()
  59. {
  60. [[NSNotificationCenter defaultCenter] removeObserver: view];
  61. [renderContext clearDrawable];
  62. [renderContext setView: nil];
  63. [view setOpenGLContext: nil];
  64. renderContext = nil;
  65. }
  66. void initialiseOnRenderThread (OpenGLContext&) {}
  67. void shutdownOnRenderThread() { deactivateCurrentContext(); }
  68. bool createdOk() const noexcept { return getRawContext() != nullptr; }
  69. void* getRawContext() const noexcept { return static_cast <void*> (renderContext); }
  70. GLuint getFrameBufferID() const noexcept { return 0; }
  71. bool makeActive() const noexcept
  72. {
  73. jassert (renderContext != nil);
  74. if ([renderContext view] != view)
  75. [renderContext setView: view];
  76. if (NSOpenGLContext* context = [view openGLContext])
  77. {
  78. [context makeCurrentContext];
  79. return true;
  80. }
  81. return false;
  82. }
  83. bool isActive() const noexcept
  84. {
  85. return [NSOpenGLContext currentContext] == renderContext;
  86. }
  87. static void deactivateCurrentContext()
  88. {
  89. [NSOpenGLContext clearCurrentContext];
  90. }
  91. struct Locker
  92. {
  93. Locker (NativeContext& nc) : cglContext ((CGLContextObj) [nc.renderContext CGLContextObj])
  94. {
  95. CGLLockContext (cglContext);
  96. }
  97. ~Locker()
  98. {
  99. CGLUnlockContext (cglContext);
  100. }
  101. private:
  102. CGLContextObj cglContext;
  103. };
  104. void swapBuffers()
  105. {
  106. [renderContext flushBuffer];
  107. }
  108. void updateWindowPosition (const Rectangle<int>&) {}
  109. bool setSwapInterval (int numFramesPerSwap)
  110. {
  111. [renderContext setValues: (const GLint*) &numFramesPerSwap
  112. forParameter: NSOpenGLCPSwapInterval];
  113. return true;
  114. }
  115. int getSwapInterval() const
  116. {
  117. GLint numFrames = 0;
  118. [renderContext getValues: &numFrames
  119. forParameter: NSOpenGLCPSwapInterval];
  120. return numFrames;
  121. }
  122. NSOpenGLContext* renderContext;
  123. NSOpenGLView* view;
  124. ReferenceCountedObjectPtr<ReferenceCountedObject> viewAttachment;
  125. //==============================================================================
  126. struct MouseForwardingNSOpenGLViewClass : public ObjCClass <NSOpenGLView>
  127. {
  128. MouseForwardingNSOpenGLViewClass() : ObjCClass <NSOpenGLView> ("JUCEGLView_")
  129. {
  130. addMethod (@selector (rightMouseDown:), rightMouseDown, "v@:@");
  131. addMethod (@selector (rightMouseUp:), rightMouseUp, "v@:@");
  132. addMethod (@selector (acceptsFirstMouse:), acceptsFirstMouse, "v@:@");
  133. registerClass();
  134. }
  135. private:
  136. static void rightMouseDown (id self, SEL, NSEvent* ev) { [[(NSOpenGLView*) self superview] rightMouseDown: ev]; }
  137. static void rightMouseUp (id self, SEL, NSEvent* ev) { [[(NSOpenGLView*) self superview] rightMouseUp: ev]; }
  138. static BOOL acceptsFirstMouse (id, SEL, NSEvent*) { return YES; }
  139. };
  140. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeContext)
  141. };
  142. //==============================================================================
  143. bool OpenGLHelpers::isContextActive()
  144. {
  145. return CGLGetCurrentContext() != 0;
  146. }