PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/jogl-1.1.1a/jogl/src/native/jogl/MacOSXWindowSystemInterface.m

#
Objective C | 696 lines | 568 code | 86 blank | 42 comment | 84 complexity | cd9d26c1cb643326d974b44121eb4897 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /* Note: usage of AvailabilityMacros.h to detect whether we're
  2. building on OS X 10.3 does not work because the header #defines
  3. MAC_OS_X_VERSION_10_4 even though the machine is a 10.3 machine
  4. #include <AvailabilityMacros.h>
  5. #ifndef MAC_OS_X_VERSION_10_3
  6. #error building JOGL requires Mac OS X 10.3 or greater
  7. #endif
  8. #ifndef MAC_OS_X_VERSION_10_4
  9. #define NSOpenGLPFAColorFloat kCGLPFAColorFloat
  10. #define kCGLNoError 0
  11. #endif
  12. */
  13. #import <Cocoa/Cocoa.h>
  14. #import <OpenGL/gl.h>
  15. #import <OpenGL/CGLTypes.h>
  16. #import <jni.h>
  17. #import "ContextUpdater.h"
  18. #import "macosx-window-system.h"
  19. // see MacOSXPbufferGLContext.java createPbuffer
  20. #define USE_GL_TEXTURE_RECTANGLE_EXT
  21. #ifdef USE_GL_TEXTURE_RECTANGLE_EXT
  22. #ifndef GL_TEXTURE_RECTANGLE_EXT
  23. #define GL_TEXTURE_RECTANGLE_EXT 0x84F5
  24. #endif
  25. #endif
  26. // Workarounds for compiling on 10.3
  27. #ifndef kCGLRGBA16161616Bit
  28. #define kCGLRGBA16161616Bit 0x00800000 /* 64 argb bit/pixel, R=63:48, G=47:32, B=31:16, A=15:0 */
  29. #define kCGLRGBFloat64Bit 0x01000000 /* 64 rgb bit/pixel, half float */
  30. #define kCGLRGBAFloat64Bit 0x02000000 /* 64 argb bit/pixel, half float */
  31. #define kCGLRGBFloat128Bit 0x04000000 /* 128 rgb bit/pixel, ieee float */
  32. #define kCGLRGBAFloat128Bit 0x08000000 /* 128 argb bit/pixel, ieee float */
  33. #define kCGLRGBFloat256Bit 0x10000000 /* 256 rgb bit/pixel, ieee double */
  34. #define kCGLRGBAFloat256Bit 0x20000000 /* 256 argb bit/pixel, ieee double */
  35. #endif
  36. struct _RendererInfo
  37. {
  38. long id; // kCGLRPRendererID
  39. long displayMask; // kCGLRPDisplayMask
  40. long accelerated; // kCGLRPAccelerated
  41. long window; // kCGLRPWindow
  42. long fullscreen; // kCGLRPFullScreen
  43. long multiscreen; // kCGLRPMultiScreen
  44. long offscreen; // kCGLRPOffScreen
  45. long floatPixels; // see kCGLRPColorModes
  46. long stereo; // kCGLRPBufferModes
  47. long auxBuffers; // kCGLRPMaxAuxBuffers
  48. long sampleBuffers; // kCGLRPMaxSampleBuffers
  49. long samples; // kCGLRPMaxSamples
  50. long samplesModes; // kCGLRPSampleModes
  51. long multiSample; // see kCGLRPSampleModes
  52. long superSample; // see kCGLRPSampleModes
  53. long alphaSample; // kCGLRPSampleAlpha
  54. long colorModes; // kCGLRPColorModes
  55. long colorRGBSizeMAX;
  56. long colorASizeMAX;
  57. long colorFloatRGBSizeMAX;
  58. long colorFloatASizeMAX;
  59. long colorFloatRGBSizeMIN;
  60. long colorFloatASizeMIN;
  61. long colorModesCount;
  62. long colorFloatModesCount;
  63. long depthModes; // kCGLRPDepthModes
  64. long depthSizeMAX;
  65. long depthModesCount;
  66. long stencilModes; // kCGLRPStencilModes
  67. long stencilSizeMAX;
  68. long stencilModesCount;
  69. long accumModes; // kCGLRPAccumModes
  70. long accumRGBSizeMAX;
  71. long accumASizeMAX;
  72. long accumModesCount;
  73. }
  74. typedef RendererInfo;
  75. RendererInfo *gRenderers = NULL;
  76. long gRenderersCount = 0;
  77. long depthModes[] = {
  78. kCGL0Bit,
  79. kCGL1Bit,
  80. kCGL2Bit,
  81. kCGL3Bit,
  82. kCGL4Bit,
  83. kCGL5Bit,
  84. kCGL6Bit,
  85. kCGL8Bit,
  86. kCGL10Bit,
  87. kCGL12Bit,
  88. kCGL16Bit,
  89. kCGL24Bit,
  90. kCGL32Bit,
  91. kCGL48Bit,
  92. kCGL64Bit,
  93. kCGL96Bit,
  94. kCGL128Bit,
  95. 0
  96. };
  97. long depthModesBits[] = {0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 24, 32, 48, 64, 96, 128};
  98. long colorModes[] = {
  99. kCGLRGB444Bit,
  100. kCGLARGB4444Bit,
  101. kCGLRGB444A8Bit,
  102. kCGLRGB555Bit,
  103. kCGLARGB1555Bit,
  104. kCGLRGB555A8Bit,
  105. kCGLRGB565Bit,
  106. kCGLRGB565A8Bit,
  107. kCGLRGB888Bit,
  108. kCGLARGB8888Bit,
  109. kCGLRGB888A8Bit,
  110. kCGLRGB101010Bit,
  111. kCGLARGB2101010Bit,
  112. kCGLRGB101010_A8Bit,
  113. kCGLRGB121212Bit,
  114. kCGLARGB12121212Bit,
  115. kCGLRGB161616Bit,
  116. kCGLRGBA16161616Bit,
  117. kCGLRGBFloat64Bit,
  118. kCGLRGBAFloat64Bit,
  119. kCGLRGBFloat128Bit,
  120. kCGLRGBAFloat128Bit,
  121. kCGLRGBFloat256Bit,
  122. kCGLRGBAFloat256Bit,
  123. 0
  124. };
  125. long colorModesBitsRGB[] = {4, 4, 4, 5, 5, 5, 5, 5, 8, 8, 8, 10, 10, 10, 12, 12, 16, 16, 16, 16, 32, 32, 64, 64};
  126. long colorModesBitsA[] = {0, 4, 8, 0, 1, 8, 0, 8, 0, 8, 8, 0, 2, 8, 0, 12, 0, 16, 0, 16, 0, 32, 0, 64};
  127. void getRendererInfo()
  128. {
  129. if (gRenderersCount == 0)
  130. {
  131. CGLRendererInfoObj info;
  132. CGLError err = CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &gRenderersCount);
  133. if (err == 0 /* kCGLNoError */)
  134. {
  135. // how many renderers are available?
  136. CGLDescribeRenderer(info, 0, kCGLRPRendererCount, &gRenderersCount);
  137. // allocate our global renderers info
  138. gRenderers = (RendererInfo*)malloc(gRenderersCount*sizeof(RendererInfo));
  139. memset(gRenderers, 0x00, gRenderersCount*sizeof(RendererInfo));
  140. // iterate through the renderers checking for their features
  141. long j;
  142. for (j=0; j<gRenderersCount; j++)
  143. {
  144. RendererInfo *renderer = &gRenderers[j];
  145. int i;
  146. CGLDescribeRenderer(info, j, kCGLRPRendererID, &(renderer->id));
  147. CGLDescribeRenderer(info, j, kCGLRPDisplayMask, &(renderer->displayMask));
  148. CGLDescribeRenderer(info, j, kCGLRPAccelerated, &(renderer->accelerated));
  149. CGLDescribeRenderer(info, j, kCGLRPWindow, &(renderer->window));
  150. CGLDescribeRenderer(info, j, kCGLRPFullScreen, &(renderer->fullscreen));
  151. CGLDescribeRenderer(info, j, kCGLRPMultiScreen, &(renderer->multiscreen));
  152. CGLDescribeRenderer(info, j, kCGLRPOffScreen, &(renderer->offscreen));
  153. CGLDescribeRenderer(info, j, kCGLRPColorModes, &(renderer->floatPixels));
  154. if ((renderer->floatPixels >= kCGLRGBFloat64Bit) != 0)
  155. {
  156. renderer->floatPixels = 1;
  157. }
  158. else
  159. {
  160. renderer->floatPixels = 0;
  161. }
  162. CGLDescribeRenderer(info, j, kCGLRPBufferModes, &(renderer->stereo));
  163. if ((renderer->stereo & kCGLStereoscopicBit) != 0)
  164. {
  165. renderer->stereo = 1;
  166. }
  167. else
  168. {
  169. renderer->stereo = 0;
  170. }
  171. CGLDescribeRenderer(info, j, kCGLRPMaxAuxBuffers, &(renderer->auxBuffers));
  172. CGLDescribeRenderer(info, j, kCGLRPMaxSampleBuffers, &(renderer->sampleBuffers));
  173. CGLDescribeRenderer(info, j, kCGLRPMaxSamples, &(renderer->samples));
  174. // The following queries are only legal on 10.4
  175. // FIXME: should figure out a way to enable them dynamically
  176. #ifdef kCGLRPSampleModes
  177. CGLDescribeRenderer(info, j, kCGLRPSampleModes, &(renderer->samplesModes));
  178. if ((renderer->samplesModes & kCGLSupersampleBit) != 0)
  179. {
  180. renderer->multiSample = 1;
  181. }
  182. if ((renderer->samplesModes & kCGLMultisampleBit) != 0)
  183. {
  184. renderer->superSample = 1;
  185. }
  186. CGLDescribeRenderer(info, j, kCGLRPSampleAlpha, &(renderer->alphaSample));
  187. #endif
  188. CGLDescribeRenderer(info, j, kCGLRPColorModes, &(renderer->colorModes));
  189. i=0;
  190. int floatPixelFormatInitialized = 0;
  191. while (colorModes[i] != 0)
  192. {
  193. if ((renderer->colorModes & colorModes[i]) != 0)
  194. {
  195. // non-float color model
  196. if (colorModes[i] < kCGLRGBFloat64Bit)
  197. {
  198. // look for max color and alpha values - prefer color models that have alpha
  199. if ((colorModesBitsRGB[i] >= renderer->colorRGBSizeMAX) && (colorModesBitsA[i] >= renderer->colorASizeMAX))
  200. {
  201. renderer->colorRGBSizeMAX = colorModesBitsRGB[i];
  202. renderer->colorASizeMAX = colorModesBitsA[i];
  203. }
  204. renderer->colorModesCount++;
  205. }
  206. // float-color model
  207. if (colorModes[i] >= kCGLRGBFloat64Bit)
  208. {
  209. if (floatPixelFormatInitialized == 0)
  210. {
  211. floatPixelFormatInitialized = 1;
  212. renderer->colorFloatASizeMAX = colorModesBitsA[i];
  213. renderer->colorFloatRGBSizeMAX = colorModesBitsRGB[i];
  214. renderer->colorFloatASizeMIN = colorModesBitsA[i];
  215. renderer->colorFloatRGBSizeMIN = colorModesBitsRGB[i];
  216. }
  217. // look for max color and alpha values - prefer color models that have alpha
  218. if ((colorModesBitsRGB[i] >= renderer->colorFloatRGBSizeMAX) && (colorModesBitsA[i] >= renderer->colorFloatASizeMAX))
  219. {
  220. renderer->colorFloatRGBSizeMAX = colorModesBitsRGB[i];
  221. renderer->colorFloatASizeMAX = colorModesBitsA[i];
  222. }
  223. // find min color
  224. if (colorModesBitsA[i] < renderer->colorFloatASizeMIN)
  225. {
  226. renderer->colorFloatASizeMIN = colorModesBitsA[i];
  227. }
  228. // find min alpha color
  229. if (colorModesBitsA[i] < renderer->colorFloatRGBSizeMIN)
  230. {
  231. renderer->colorFloatRGBSizeMIN = colorModesBitsRGB[i];
  232. }
  233. renderer->colorFloatModesCount++;
  234. }
  235. }
  236. i++;
  237. }
  238. CGLDescribeRenderer(info, j, kCGLRPDepthModes, &(renderer->depthModes));
  239. i=0;
  240. while (depthModes[i] != 0)
  241. {
  242. if ((renderer->depthModes & depthModes[i]) != 0)
  243. {
  244. renderer->depthSizeMAX = depthModesBits[i];
  245. renderer->depthModesCount++;
  246. }
  247. i++;
  248. }
  249. CGLDescribeRenderer(info, j, kCGLRPStencilModes, &(renderer->stencilModes));
  250. i=0;
  251. while (depthModes[i] != 0)
  252. {
  253. if ((renderer->stencilModes & depthModes[i]) != 0)
  254. {
  255. renderer->stencilSizeMAX = depthModesBits[i];
  256. renderer->stencilModesCount++;
  257. }
  258. i++;
  259. }
  260. CGLDescribeRenderer(info, j, kCGLRPAccumModes, &(renderer->accumModes));
  261. i=0;
  262. while (colorModes[i] != 0)
  263. {
  264. if ((renderer->accumModes & colorModes[i]) != 0)
  265. {
  266. if ((colorModesBitsRGB[i] >= renderer->accumRGBSizeMAX) && (colorModesBitsA[i] >= renderer->accumASizeMAX))
  267. {
  268. renderer->accumRGBSizeMAX = colorModesBitsRGB[i];
  269. renderer->accumASizeMAX = colorModesBitsA[i];
  270. }
  271. renderer->accumModesCount++;
  272. }
  273. i++;
  274. }
  275. }
  276. }
  277. CGLDestroyRendererInfo (info);
  278. }
  279. #if 0
  280. fprintf(stderr, "gRenderersCount=%ld\n", gRenderersCount);
  281. int j;
  282. for (j=0; j<gRenderersCount; j++)
  283. {
  284. RendererInfo *renderer = &gRenderers[j];
  285. fprintf(stderr, " id=%ld\n", renderer->id);
  286. fprintf(stderr, " displayMask=%ld\n", renderer->displayMask);
  287. fprintf(stderr, " accelerated=%ld\n", renderer->accelerated);
  288. fprintf(stderr, " window=%ld\n", renderer->window);
  289. fprintf(stderr, " fullscreen=%ld\n", renderer->fullscreen);
  290. fprintf(stderr, " multiscreen=%ld\n", renderer->multiscreen);
  291. fprintf(stderr, " offscreen=%ld\n", renderer->offscreen);
  292. fprintf(stderr, " floatPixels=%ld\n", renderer->floatPixels);
  293. fprintf(stderr, " stereo=%ld\n", renderer->stereo);
  294. fprintf(stderr, " auxBuffers=%ld\n", renderer->auxBuffers);
  295. fprintf(stderr, " sampleBuffers=%ld\n", renderer->sampleBuffers);
  296. fprintf(stderr, " samples=%ld\n", renderer->samples);
  297. fprintf(stderr, " samplesModes=%ld\n", renderer->samplesModes);
  298. fprintf(stderr, " multiSample=%ld\n", renderer->superSample);
  299. fprintf(stderr, " superSample=%ld\n", renderer->superSample);
  300. fprintf(stderr, " alphaSample=%ld\n", renderer->alphaSample);
  301. fprintf(stderr, " colorModes=%ld\n", renderer->colorModes);
  302. fprintf(stderr, " colorRGBSizeMAX=%ld\n", renderer->colorRGBSizeMAX);
  303. fprintf(stderr, " colorASizeMAX=%ld\n", renderer->colorASizeMAX);
  304. fprintf(stderr, " colorFloatRGBSizeMAX=%ld\n", renderer->colorFloatRGBSizeMAX);
  305. fprintf(stderr, " colorFloatASizeMAX=%ld\n", renderer->colorFloatASizeMAX);
  306. fprintf(stderr, " colorFloatRGBSizeMIN=%ld\n", renderer->colorFloatRGBSizeMIN);
  307. fprintf(stderr, " colorFloatASizeMIN=%ld\n", renderer->colorFloatASizeMIN);
  308. fprintf(stderr, " colorModesCount=%ld\n", renderer->colorModesCount);
  309. fprintf(stderr, " colorFloatModesCount=%ld\n", renderer->colorFloatModesCount);
  310. fprintf(stderr, " depthModes=%ld\n", renderer->depthModes);
  311. fprintf(stderr, " depthSizeMAX=%ld\n", renderer->depthSizeMAX);
  312. fprintf(stderr, " depthModesCount=%ld\n", renderer->depthModesCount);
  313. fprintf(stderr, " stencilModes=%ld\n", renderer->stencilModes);
  314. fprintf(stderr, " stencilSizeMAX=%ld\n", renderer->stencilSizeMAX);
  315. fprintf(stderr, " stencilModesCount=%ld\n", renderer->stencilModesCount);
  316. fprintf(stderr, " accumModes=%ld\n", renderer->accumModes);
  317. fprintf(stderr, " accumRGBSizeMAX=%ld\n", renderer->accumRGBSizeMAX);
  318. fprintf(stderr, " accumASizeMAX=%ld\n", renderer->accumASizeMAX);
  319. fprintf(stderr, " accumModesCount=%ld\n", renderer->accumModesCount);
  320. fprintf(stderr, "\n");
  321. }
  322. #endif
  323. }
  324. long validateParameter(NSOpenGLPixelFormatAttribute attribute, long value)
  325. {
  326. int i;
  327. for (i=0; i<gRenderersCount; i++) {
  328. RendererInfo* renderer = &gRenderers[i];
  329. if (renderer->accelerated != 0) {
  330. switch (attribute) {
  331. case NSOpenGLPFAStereo:
  332. return renderer->stereo;
  333. case NSOpenGLPFAStencilSize:
  334. return MIN(value, renderer->stencilSizeMAX);
  335. default:
  336. break;
  337. }
  338. }
  339. }
  340. return value;
  341. }
  342. void* createPixelFormat(int* iattrs, int niattrs, int* ivalues) {
  343. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  344. getRendererInfo();
  345. // http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/ObjC_classic/Classes/NSOpenGLPixelFormat.html
  346. NSOpenGLPixelFormatAttribute attribs[256];
  347. int idx = 0;
  348. int i;
  349. for (i = 0; i < niattrs; i++) {
  350. int attr = iattrs[i];
  351. switch (attr) {
  352. case NSOpenGLPFAPixelBuffer:
  353. if (ivalues[i] != 0) {
  354. attribs[idx++] = NSOpenGLPFAPixelBuffer;
  355. }
  356. break;
  357. case kCGLPFAColorFloat:
  358. if (ivalues[i] != 0) {
  359. attribs[idx++] = kCGLPFAColorFloat;
  360. }
  361. break;
  362. case NSOpenGLPFADoubleBuffer:
  363. if (ivalues[i] != 0) {
  364. attribs[idx++] = NSOpenGLPFADoubleBuffer;
  365. }
  366. break;
  367. case NSOpenGLPFAStereo:
  368. if (ivalues[i] != 0 && (validateParameter(NSOpenGLPFAStereo, 0 /* dummy */) != 0)) {
  369. attribs[idx++] = NSOpenGLPFAStereo;
  370. }
  371. break;
  372. case NSOpenGLPFAColorSize:
  373. case NSOpenGLPFAAlphaSize:
  374. case NSOpenGLPFADepthSize:
  375. case NSOpenGLPFAAccumSize:
  376. case NSOpenGLPFASampleBuffers:
  377. case NSOpenGLPFASamples:
  378. attribs[idx++] = attr;
  379. attribs[idx++] = ivalues[i];
  380. break;
  381. case NSOpenGLPFAStencilSize:
  382. attribs[idx++] = attr;
  383. attribs[idx++] = validateParameter(NSOpenGLPFAStencilSize, ivalues[i]);
  384. break;
  385. default:
  386. // Need better way to signal to caller
  387. return nil;
  388. }
  389. }
  390. // Zero-terminate
  391. attribs[idx++] = 0;
  392. NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
  393. if (fmt == nil) {
  394. // should we fallback to defaults or not?
  395. fmt = [NSOpenGLView defaultPixelFormat];
  396. }
  397. [pool release];
  398. return fmt;
  399. }
  400. void queryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues) {
  401. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  402. NSOpenGLPixelFormat* fmt = (NSOpenGLPixelFormat*) pixelFormat;
  403. long tmp;
  404. // FIXME: think about how specifying this might affect the API
  405. int virtualScreen = 0;
  406. int i;
  407. for (i = 0; i < niattrs; i++) {
  408. [fmt getValues: &tmp
  409. forAttribute: (NSOpenGLPixelFormatAttribute) iattrs[i]
  410. forVirtualScreen: virtualScreen];
  411. ivalues[i] = (int) tmp;
  412. }
  413. [pool release];
  414. }
  415. void deletePixelFormat(void* pixelFormat) {
  416. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  417. NSOpenGLPixelFormat* fmt = (NSOpenGLPixelFormat*) pixelFormat;
  418. [fmt release];
  419. [pool release];
  420. }
  421. void* createContext(void* shareContext,
  422. void* view,
  423. void* pixelFormat,
  424. int* viewNotReady)
  425. {
  426. getRendererInfo();
  427. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  428. NSView *nsView = (NSView*)view;
  429. if (nsView != NULL)
  430. {
  431. Bool viewReady = true;
  432. if ([nsView lockFocusIfCanDraw] == NO)
  433. {
  434. viewReady = false;
  435. }
  436. else
  437. {
  438. NSRect frame = [nsView frame];
  439. if ((frame.size.width == 0) || (frame.size.height == 0))
  440. {
  441. [nsView unlockFocus];
  442. viewReady = false;
  443. }
  444. }
  445. if (!viewReady)
  446. {
  447. if (viewNotReady != NULL)
  448. {
  449. *viewNotReady = 1;
  450. }
  451. // the view is not ready yet
  452. [pool release];
  453. return NULL;
  454. }
  455. }
  456. NSOpenGLContext* nsContext = [[NSOpenGLContext alloc]
  457. initWithFormat: (NSOpenGLPixelFormat*) pixelFormat
  458. shareContext: (NSOpenGLContext*) shareContext];
  459. if (nsContext != nil) {
  460. if (nsView != nil) {
  461. [nsContext setView:nsView];
  462. [nsView unlockFocus];
  463. }
  464. }
  465. [pool release];
  466. return nsContext;
  467. }
  468. Bool makeCurrentContext(void* context) {
  469. NSOpenGLContext *nsContext = (NSOpenGLContext*)context;
  470. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  471. [nsContext makeCurrentContext];
  472. [pool release];
  473. return true;
  474. }
  475. Bool clearCurrentContext(void* context) {
  476. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  477. [NSOpenGLContext clearCurrentContext];
  478. [pool release];
  479. return true;
  480. }
  481. Bool deleteContext(void* context) {
  482. NSOpenGLContext *nsContext = (NSOpenGLContext*)context;
  483. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  484. [nsContext clearDrawable];
  485. [nsContext release];
  486. [pool release];
  487. return true;
  488. }
  489. Bool flushBuffer(void* context) {
  490. NSOpenGLContext *nsContext = (NSOpenGLContext*)context;
  491. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  492. [nsContext flushBuffer];
  493. [pool release];
  494. return true;
  495. }
  496. void updateContext(void* context) {
  497. NSOpenGLContext *nsContext = (NSOpenGLContext*)context;
  498. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  499. [nsContext update];
  500. [pool release];
  501. }
  502. void copyContext(void* destContext, void* srcContext, int mask) {
  503. NSOpenGLContext *src = (NSOpenGLContext*) srcContext;
  504. NSOpenGLContext *dst = (NSOpenGLContext*) destContext;
  505. [dst copyAttributesFromContext: src withMask: mask];
  506. }
  507. void* updateContextRegister(void* context, void* view) {
  508. NSOpenGLContext *nsContext = (NSOpenGLContext*)context;
  509. NSView *nsView = (NSView*)view;
  510. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  511. ContextUpdater *contextUpdater = [[ContextUpdater alloc] init];
  512. [contextUpdater registerFor:nsContext with:nsView];
  513. [pool release];
  514. return NULL;
  515. }
  516. void updateContextUnregister(void* context, void* view, void* updater) {
  517. ContextUpdater *contextUpdater = (ContextUpdater *)updater;
  518. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  519. [contextUpdater release];
  520. [pool release];
  521. }
  522. void* createPBuffer(int renderTarget, int internalFormat, int width, int height) {
  523. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  524. NSOpenGLPixelBuffer* pBuffer = [[NSOpenGLPixelBuffer alloc]
  525. initWithTextureTarget:renderTarget
  526. textureInternalFormat:internalFormat
  527. textureMaxMipMapLevel:0
  528. pixelsWide:width
  529. pixelsHigh:height];
  530. [pool release];
  531. return pBuffer;
  532. }
  533. Bool destroyPBuffer(void* context, void* buffer) {
  534. /* FIXME: not clear whether we need to perform the clearDrawable below */
  535. /* FIXME: remove the context argument -- don't need it any more */
  536. /* NSOpenGLContext *nsContext = (NSOpenGLContext*)context; */
  537. NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer;
  538. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  539. /*
  540. if (nsContext != NULL) {
  541. [nsContext clearDrawable];
  542. }
  543. */
  544. [pBuffer release];
  545. [pool release];
  546. return true;
  547. }
  548. void setContextPBuffer(void* context, void* buffer) {
  549. NSOpenGLContext *nsContext = (NSOpenGLContext*)context;
  550. NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer;
  551. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  552. [nsContext setPixelBuffer: pBuffer
  553. cubeMapFace: 0
  554. mipMapLevel: 0
  555. currentVirtualScreen: [nsContext currentVirtualScreen]];
  556. [pool release];
  557. }
  558. void setContextTextureImageToPBuffer(void* context, void* buffer, int colorBuffer) {
  559. NSOpenGLContext *nsContext = (NSOpenGLContext*)context;
  560. NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer;
  561. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  562. [nsContext setTextureImageToPixelBuffer: pBuffer
  563. colorBuffer: (unsigned long) colorBuffer];
  564. [pool release];
  565. }
  566. #include <mach-o/dyld.h>
  567. Bool imagesInitialized = false;
  568. static char libGLStr[] = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib";
  569. static char libGLUStr[] = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib";
  570. static const struct mach_header *libGLImage;
  571. static const struct mach_header *libGLUImage;
  572. void* getProcAddress(const char *procname) {
  573. if (imagesInitialized == false) {
  574. imagesInitialized = true;
  575. unsigned long options = NSADDIMAGE_OPTION_RETURN_ON_ERROR;
  576. libGLImage = NSAddImage(libGLStr, options);
  577. libGLUImage = NSAddImage(libGLUStr, options);
  578. }
  579. unsigned long options = NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR;
  580. char underscoreName[512] = "_";
  581. strcat(underscoreName, procname);
  582. if (NSIsSymbolNameDefinedInImage(libGLImage, underscoreName) == YES) {
  583. NSSymbol sym = NSLookupSymbolInImage(libGLImage, underscoreName, options);
  584. return NSAddressOfSymbol(sym);
  585. }
  586. if (NSIsSymbolNameDefinedInImage(libGLUImage, underscoreName) == YES) {
  587. NSSymbol sym = NSLookupSymbolInImage(libGLUImage, underscoreName, options);
  588. return NSAddressOfSymbol(sym);
  589. }
  590. if (NSIsSymbolNameDefinedWithHint(underscoreName, "GL")) {
  591. NSSymbol sym = NSLookupAndBindSymbol(underscoreName);
  592. return NSAddressOfSymbol(sym);
  593. }
  594. return NULL;
  595. }
  596. void setSwapInterval(void* context, int interval) {
  597. NSOpenGLContext *nsContext = (NSOpenGLContext*)context;
  598. long swapInterval = interval;
  599. [nsContext setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
  600. }
  601. Bool setGammaRamp(int tableSize, float* redRamp, float* greenRamp, float* blueRamp) {
  602. CGDisplayErr err = CGSetDisplayTransferByTable(kCGDirectMainDisplay, tableSize, redRamp, greenRamp, blueRamp);
  603. return (err == CGDisplayNoErr);
  604. }
  605. void resetGammaRamp() {
  606. CGDisplayRestoreColorSyncSettings();
  607. }