VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_agl.c@ 18568

Last change on this file since 18568 was 18568, checked in by vboxsync, 16 years ago

crOpenGL-OSX: burn fix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 26.0 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include <Carbon/Carbon.h>
8#include <AGL/agl.h>
9#include <OpenGL/OpenGL.h>
10
11#include <iprt/time.h>
12#include <iprt/assert.h>
13
14#include <stdio.h>
15
16#include "cr_environment.h"
17#include "cr_error.h"
18#include "cr_string.h"
19#include "cr_mem.h"
20#include "renderspu.h"
21
22/* Some necessary global defines */
23WindowGroupRef gParentGroup = NULL;
24WindowGroupRef gMasterGroup = NULL;
25GLint gCurrentBufferName = 1;
26uint64_t gDockUpdateTS = 0;
27
28enum
29{
30 /* Event classes */
31 kEventClassVBox = 'vbox',
32 /* Event kinds */
33 kEventVBoxShowWindow = 'swin',
34 kEventVBoxHideWindow = 'hwin',
35 kEventVBoxMoveWindow = 'mwin',
36 kEventVBoxResizeWindow = 'rwin',
37 kEventVBoxDisposeWindow = 'dwin',
38 kEventVBoxUpdateDock = 'udck'
39};
40
41#ifdef __LP64__ /** @todo port to 64-bit darwin. */
42# define renderspuSetWindowContext(w, c) \
43 AssertFailed()
44# define renderspuGetWindowContext(w) \
45 ( (ContextInfo *) GetWRefCon( ((w)->nativeWindow ? (w)->nativeWindow : (w)->window) ) )
46#else
47# define renderspuSetWindowContext(w, c) \
48 ( SetWRefCon( (w), (unsigned long) (c) ) )
49# define renderspuGetWindowContext(w) \
50 ( (ContextInfo *) GetWRefCon( ((w)->nativeWindow ? (w)->nativeWindow : (w)->window) ) )
51#endif
52
53/* Debug macros */
54#ifdef DEBUG_poetzsch
55#define DEBUG_MSG_POETZSCH(text) \
56 printf text
57#else
58#define DEBUG_MSG_POETZSCH(text) \
59 do {} while (0)
60#endif
61
62#define DEBUG_MSG_RESULT(result, text) \
63 crDebug(text" (%d; %s:%d)", (int)(result), __FILE__, __LINE__)
64
65#define CHECK_CARBON_RC(result, text) \
66 if((result) != noErr) \
67 DEBUG_MSG_RESULT(result, text);
68
69#define CHECK_CARBON_RC_RETURN(result, text, ret) \
70 if((result) != noErr) \
71 { \
72 DEBUG_MSG_RESULT(result, text); \
73 return ret; \
74 }
75
76#define CHECK_CARBON_RC_RETURN_VOID(result, text) \
77 CHECK_CARBON_RC_RETURN(result, text,)
78
79#define CHECK_AGL_RC(result, text) \
80 if(!(result)) \
81 { \
82 GLenum error = render_spu.ws.aglGetError(); \
83 DEBUG_MSG_RESULT(result, text); \
84 }
85
86/* Window event handler */
87static pascal OSStatus
88windowEvtHndlr(EventHandlerCallRef myHandler, EventRef event, void* userData)
89{
90 /* Currently this is *NOT* used */
91
92#pragma unused (userData)
93 WindowRef window = NULL;
94 Rect rectPort = { 0, 0, 0, 0 };
95 OSStatus result = eventNotHandledErr;
96 UInt32 class = GetEventClass( event );
97 UInt32 kind = GetEventKind( event );
98
99 GetEventParameter(event, kEventParamDirectObject, typeWindowRef,
100 NULL, sizeof(WindowRef), NULL, &window);
101 if( window )
102 GetWindowPortBounds( window, &rectPort );
103
104 switch (class) {
105 case kEventClassWindow:
106 switch (kind) {
107 case kEventWindowActivated:
108#ifndef __LP64__ /* not available for 64-bit processes? */
109 case kEventWindowDrawContent:
110#endif
111 break;
112
113 case kEventWindowClose:
114 HideWindow( window );
115#ifdef __LP64__ /** @todo port to 64-bit darwin. */
116#else
117 SetWRefCon( window, (int)NULL );
118#endif
119
120 crWarning( "Render SPU: caught kEventWindowClose -- quitting." );
121 break;
122
123 case kEventWindowShown:
124 /* build gl */
125#ifndef __LP64__ /** @todo port to 64-bit darwin! Need to cehck if this event is generated or not (it probably isn't). */
126 if( window == FrontWindow() )
127 SetUserFocusWindow( window );
128 InvalWindowRect( window, &rectPort );
129#endif
130 break;
131
132 case kEventWindowBoundsChanged:
133 /* resize
134 update */
135 break;
136
137 case kEventWindowZoomed:
138 /* zoom button */
139 break;
140 }
141 break;
142 }
143
144 return result;
145}
146
147GLboolean
148renderspu_SystemInitVisual(VisualInfo *visual)
149{
150 if(visual->visAttribs & CR_PBUFFER_BIT)
151 crWarning("Render SPU: PBuffers not support on Darwin/AGL yet.");
152
153 return GL_TRUE;
154}
155
156GLboolean
157renderspuChoosePixelFormat(ContextInfo *context, AGLPixelFormat *pix)
158{
159 GLbitfield visAttribs = context->visual->visAttribs;
160 GLint attribs[32];
161 GLint ind = 0;
162
163#define ATTR_ADD(s) ( attribs[ind++] = (s) )
164#define ATTR_ADDV(s,v) ( ATTR_ADD((s)), ATTR_ADD((v)) )
165
166 CRASSERT(render_spu.ws.aglChoosePixelFormat);
167
168 ATTR_ADD(AGL_RGBA);
169/* ATTR_ADDV(AGL_RED_SIZE, 1);
170 ATTR_ADDV(AGL_GREEN_SIZE, 1);
171 ATTR_ADDV(AGL_BLUE_SIZE, 1); */
172
173/* if( render_spu.fullscreen )*/
174/* ATTR_ADD(AGL_FULLSCREEN);*/
175
176 if( visAttribs & CR_ALPHA_BIT )
177 ATTR_ADDV(AGL_ALPHA_SIZE, 1);
178
179 if( visAttribs & CR_DOUBLE_BIT )
180 ATTR_ADD(AGL_DOUBLEBUFFER);
181
182 if( visAttribs & CR_STEREO_BIT )
183 ATTR_ADD(AGL_STEREO);
184
185 if( visAttribs & CR_DEPTH_BIT )
186 ATTR_ADDV(AGL_DEPTH_SIZE, 1);
187
188 if( visAttribs & CR_STENCIL_BIT )
189 ATTR_ADDV(AGL_STENCIL_SIZE, 1);
190
191 if( visAttribs & CR_ACCUM_BIT ) {
192 ATTR_ADDV(AGL_ACCUM_RED_SIZE, 1);
193 ATTR_ADDV(AGL_ACCUM_GREEN_SIZE, 1);
194 ATTR_ADDV(AGL_ACCUM_BLUE_SIZE, 1);
195 if( visAttribs & CR_ALPHA_BIT )
196 ATTR_ADDV(AGL_ACCUM_ALPHA_SIZE, 1);
197 }
198
199 if( visAttribs & CR_MULTISAMPLE_BIT ) {
200 ATTR_ADDV(AGL_SAMPLE_BUFFERS_ARB, 1);
201 ATTR_ADDV(AGL_SAMPLES_ARB, 4);
202 }
203
204 if( visAttribs & CR_OVERLAY_BIT )
205 ATTR_ADDV(AGL_LEVEL, 1);
206
207 ATTR_ADD(AGL_NONE);
208
209 *pix = render_spu.ws.aglChoosePixelFormat( NULL, 0, attribs );
210
211 return (*pix != NULL);
212}
213
214void
215renderspuDestroyPixelFormat(ContextInfo *context, AGLPixelFormat *pix)
216{
217 render_spu.ws.aglDestroyPixelFormat( *pix );
218 *pix = NULL;
219}
220
221GLboolean
222renderspu_SystemCreateContext(VisualInfo *visual, ContextInfo *context, ContextInfo *sharedContext)
223{
224 AGLPixelFormat pix;
225
226 (void) sharedContext;
227 CRASSERT(visual);
228 CRASSERT(context);
229
230 context->visual = visual;
231
232 if( !renderspuChoosePixelFormat(context, &pix) ) {
233 crError( "Render SPU: Unable to create pixel format" );
234 return GL_FALSE;
235 }
236
237 context->context = render_spu.ws.aglCreateContext( pix, NULL );
238 renderspuDestroyPixelFormat( context, &pix );
239
240 if( !context->context ) {
241 crError( "Render SPU: Could not create rendering context" );
242 return GL_FALSE;
243 }
244
245 return GL_TRUE;
246}
247
248void
249renderspu_SystemDestroyContext(ContextInfo *context)
250{
251 if(!context)
252 return;
253
254 render_spu.ws.aglSetDrawable(context->context, NULL);
255 render_spu.ws.aglSetCurrentContext(NULL);
256 if(context->context)
257 {
258 render_spu.ws.aglDestroyContext(context->context);
259 context->context = NULL;
260 }
261
262 context->visual = NULL;
263}
264
265void
266renderspuFullscreen(WindowInfo *window, GLboolean fullscreen)
267{
268 /* Real fullscreen isn't supported by VirtualBox */
269}
270
271GLboolean
272renderspuWindowAttachContext(WindowInfo *wi, WindowRef window,
273 ContextInfo *context)
274{
275 GLboolean result;
276
277 if(!context || !wi)
278 return render_spu.ws.aglSetCurrentContext( NULL );
279
280 DEBUG_MSG_POETZSCH (("WindowAttachContext %d\n", wi->id));
281
282 /* Flush old context first */
283 if (context->currentWindow->window != window)
284 render_spu.self.Flush();
285 /* If the window buffer name is uninitialized we have to create a new
286 * dummy context. */
287 if (wi->bufferName == -1)
288 {
289 DEBUG_MSG_POETZSCH (("WindowAttachContext: create context %d\n", wi->id));
290 /* Use the same visual bits as those in the context structure */
291 AGLPixelFormat pix;
292 if( !renderspuChoosePixelFormat(context, &pix) )
293 {
294 crError( "Render SPU: Unable to create pixel format" );
295 return GL_FALSE;
296 }
297 /* Create the dummy context */
298 wi->dummyContext = render_spu.ws.aglCreateContext( pix, NULL );
299 renderspuDestroyPixelFormat( context, &pix );
300 if( !wi->dummyContext )
301 {
302 crError( "Render SPU: Could not create rendering context" );
303 return GL_FALSE;
304 }
305 AGLDrawable drawable;
306#ifdef __LP64__ /** @todo port to 64-bit darwin. */
307 drawable = NULL;
308#else
309 drawable = (AGLDrawable) GetWindowPort(window);
310#endif
311 /* New global buffer name */
312 wi->bufferName = gCurrentBufferName++;
313 /* Set the new buffer name to the dummy context. This enable the
314 * sharing of the same hardware buffer afterwards. */
315 result = render_spu.ws.aglSetInteger(wi->dummyContext, AGL_BUFFER_NAME, &wi->bufferName);
316 CHECK_AGL_RC (result, "Render SPU: SetInteger Failed");
317 /* Assign the dummy context to the window */
318 result = render_spu.ws.aglSetDrawable(wi->dummyContext, drawable);
319 CHECK_AGL_RC (result, "Render SPU: SetDrawable Failed");
320 }
321
322 AGLDrawable oldDrawable;
323 AGLDrawable newDrawable;
324
325 oldDrawable = render_spu.ws.aglGetDrawable(context->context);
326#ifdef __LP64__ /** @todo port to 64-bit darwin. */
327 newDrawable = oldDrawable;
328#else
329 newDrawable = (AGLDrawable) GetWindowPort(window);
330#endif
331 /* Only switch the context if the drawable has changed */
332 if (oldDrawable != newDrawable)
333 {
334 /* Reset the current context */
335 result = render_spu.ws.aglSetDrawable(context->context, NULL);
336 CHECK_AGL_RC (result, "Render SPU: SetDrawable Failed");
337 /* Set the buffer name of the dummy context to the current context
338 * also. After that both share the same hardware buffer. */
339 render_spu.ws.aglSetInteger (context->context, AGL_BUFFER_NAME, &wi->bufferName);
340 CHECK_AGL_RC (result, "Render SPU: SetInteger Failed");
341 /* Set the new drawable */
342#ifdef __LP64__ /** @todo port to 64-bit darwin. */
343 result = -1;
344#else
345 result = render_spu.ws.aglSetDrawable(context->context, newDrawable);
346#endif
347 CHECK_AGL_RC (result, "Render SPU: SetDrawable Failed");
348 renderspuSetWindowContext( window, context );
349 }
350 result = render_spu.ws.aglSetCurrentContext(context->context);
351 CHECK_AGL_RC (result, "Render SPU: SetCurrentContext Failed");
352 result = render_spu.ws.aglUpdateContext(context->context);
353 CHECK_AGL_RC (result, "Render SPU: UpdateContext Failed");
354
355 return result;
356}
357
358GLboolean
359renderspu_SystemCreateWindow(VisualInfo *visual, GLboolean showIt,
360 WindowInfo *window)
361{
362 return GL_TRUE;
363}
364
365void
366renderspu_SystemDestroyWindow(WindowInfo *window)
367{
368 CRASSERT(window);
369 CRASSERT(window->visual);
370
371 if(!window->nativeWindow)
372 {
373 EventRef evt;
374 OSStatus status = CreateEvent(NULL, kEventClassVBox, kEventVBoxDisposeWindow, 0, kEventAttributeNone, &evt);
375 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: CreateEvent Failed");
376 status = SetEventParameter(evt, kEventParamWindowRef, typeWindowRef, sizeof (window->window), &window->window);
377 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: SetEventParameter Failed");
378 status = SendEventToEventTarget (evt, GetWindowEventTarget (HIViewGetWindow ((HIViewRef)render_spu_parent_window_id)));
379 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: PostEventToQueue Failed");
380 }
381
382 /* Delete the dummy context */
383 if(window->dummyContext)
384 {
385 render_spu.ws.aglSetDrawable(window->dummyContext, NULL);
386 render_spu.ws.aglDestroyContext(window->dummyContext);
387 window->dummyContext = NULL;
388 }
389
390 /* Reset some values */
391 window->bufferName = -1;
392 window->visual = NULL;
393 window->window = NULL;
394}
395
396void
397renderspu_SystemWindowSize(WindowInfo *window, GLint w, GLint h)
398{
399 CRASSERT(window);
400 CRASSERT(window->window);
401
402 OSStatus status = noErr;
403 /* Send a event to the main thread, cause some function of Carbon aren't
404 * thread safe */
405 EventRef evt;
406 status = CreateEvent(NULL, kEventClassVBox, kEventVBoxResizeWindow, 0, kEventAttributeNone, &evt);
407 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: CreateEvent Failed");
408 status = SetEventParameter(evt, kEventParamWindowRef, typeWindowRef, sizeof(window->window), &window->window);
409 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: SetEventParameter Failed");
410 HISize s = CGSizeMake (w, h);
411 status = SetEventParameter(evt, kEventParamDimensions, typeHISize, sizeof (s), &s);
412 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: SetEventParameter Failed");
413 status = SendEventToEventTarget (evt, GetWindowEventTarget (HIViewGetWindow ((HIViewRef)render_spu_parent_window_id)));
414 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: PostEventToQueue Failed");
415
416 /* Update the context */
417 GLboolean result = true;
418 ContextInfo *context = renderspuGetWindowContext(window);
419 if (context &&
420 context->context)
421 {
422 DEBUG_MSG_POETZSCH (("Size %d context %x visible %d\n", window->id, context->context, IsWindowVisible (window->window)));
423 result = render_spu.ws.aglUpdateContext(context->context);
424 CHECK_AGL_RC (result, "Render SPU: UpdateContext Failed");
425 render_spu.self.Flush();
426 }
427 /* save the new size */
428 window->width = w;
429 window->height = h;
430}
431
432void
433renderspu_SystemGetWindowGeometry(WindowInfo *window,
434 GLint *x, GLint *y,
435 GLint *w, GLint *h)
436{
437 CRASSERT(window);
438 CRASSERT(window->window);
439
440 OSStatus status = noErr;
441 Rect r;
442 status = GetWindowBounds(window->window, kWindowStructureRgn, &r);
443 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: GetWindowBounds Failed");
444
445 *x = (int) r.left;
446 *y = (int) r.top;
447 *w = (int) (r.right - r.left);
448 *h = (int) (r.bottom - r.top);
449}
450
451void
452renderspu_SystemGetMaxWindowSize(WindowInfo *window,
453 GLint *w, GLint *h)
454{
455 CRASSERT(window);
456 CRASSERT(window->window);
457
458 OSStatus status = noErr;
459 HISize s;
460#ifdef __LP64__ /** @todo port to 64-bit darwin. */
461 status = -1;
462#else
463 status = GetWindowResizeLimits (window->window, NULL, &s);
464#endif
465 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: GetWindowResizeLimits Failed");
466
467 *w = s.width;
468 *h = s.height;
469}
470
471void
472renderspu_SystemWindowPosition(WindowInfo *window,
473 GLint x, GLint y)
474{
475 CRASSERT(window);
476 CRASSERT(window->window);
477
478 OSStatus status = noErr;
479 /* Send a event to the main thread, cause some function of Carbon aren't
480 * thread safe */
481 EventRef evt;
482 status = CreateEvent(NULL, kEventClassVBox, kEventVBoxMoveWindow, 0, kEventAttributeNone, &evt);
483 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: CreateEvent Failed");
484 status = SetEventParameter(evt, kEventParamWindowRef, typeWindowRef, sizeof(window->window), &window->window);
485 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: SetEventParameter Failed");
486 HIPoint p = CGPointMake (x, y);
487 status = SetEventParameter(evt, kEventParamOrigin, typeHIPoint, sizeof (p), &p);
488 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: SetEventParameter Failed");
489 status = SendEventToEventTarget (evt, GetWindowEventTarget (HIViewGetWindow ((HIViewRef)render_spu_parent_window_id)));
490 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: PostEventToQueue Failed");
491
492 /* Update the context */
493 GLboolean result = true;
494 ContextInfo *context = renderspuGetWindowContext(window);
495 if (context &&
496 context->context)
497 {
498 DEBUG_MSG_POETZSCH (("Position %d context %x visible %d\n", window->id, context->context, IsWindowVisible (window->window)));
499 result = render_spu.ws.aglUpdateContext(context->context);
500 CHECK_AGL_RC (result, "Render SPU: UpdateContext Failed");
501 render_spu.self.Flush();
502 }
503}
504
505/* Either show or hide the render SPU's window. */
506void
507renderspu_SystemShowWindow(WindowInfo *window, GLboolean showIt)
508{
509 CRASSERT(window);
510 CRASSERT(window->window);
511
512 if (!IsValidWindowPtr(window->window))
513 return;
514
515 if(showIt)
516 {
517 /* Force moving the win to the right position before we show it */
518 renderspu_SystemWindowPosition (window, window->x, window->y);
519 OSStatus status = noErr;
520 /* Send a event to the main thread, cause some function of Carbon
521 * aren't thread safe */
522 EventRef evt;
523 status = CreateEvent(NULL, kEventClassVBox, kEventVBoxShowWindow, 0, kEventAttributeNone, &evt);
524 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: CreateEvent Failed");
525 status = SetEventParameter(evt, kEventParamWindowRef, typeWindowRef, sizeof (window->window), &window->window);
526 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: SetEventParameter Failed");
527 status = SendEventToEventTarget (evt, GetWindowEventTarget (HIViewGetWindow ((HIViewRef)render_spu_parent_window_id)));
528 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: PostEventToQueue Failed");
529 }
530 else
531 {
532 EventRef evt;
533 OSStatus status = CreateEvent(NULL, kEventClassVBox, kEventVBoxHideWindow, 0, kEventAttributeNone, &evt);
534 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: CreateEvent Failed");
535 status = SetEventParameter(evt, kEventParamWindowRef, typeWindowRef, sizeof (window->window), &window->window);
536 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: SetEventParameter Failed");
537 status = SendEventToEventTarget (evt, GetWindowEventTarget (HIViewGetWindow ((HIViewRef)render_spu_parent_window_id)));
538 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: PostEventToQueue Failed");
539 }
540
541 /* Update the context */
542 GLboolean result = true;
543 ContextInfo *context = renderspuGetWindowContext(window);
544 if (context &&
545 context->context)
546 {
547 DEBUG_MSG_POETZSCH (("Showed %d context %x visible %d\n", window->id, context->context, IsWindowVisible (window->window)));
548 result = render_spu.ws.aglUpdateContext(context->context);
549 CHECK_AGL_RC (result, "Render SPU: UpdateContext Failed");
550 render_spu.self.Flush();
551 }
552
553 window->visible = showIt;
554}
555
556void
557renderspu_SystemMakeCurrent(WindowInfo *window, GLint nativeWindow,
558 ContextInfo *context)
559{
560 Boolean result;
561 DEBUG_MSG_POETZSCH (("makecurrent %d: \n", window->id));
562
563 CRASSERT(render_spu.ws.aglSetCurrentContext);
564 crDebug( "renderspu_SystemMakeCurrent( %x, %i, %x )", window, nativeWindow, context );
565
566 if(window && context)
567 {
568 CRASSERT(window->window);
569 CRASSERT(context->context);
570
571 if(window->visual != context->visual)
572 {
573 crDebug("Render SPU: MakeCurrent visual mismatch (0x%x != 0x%x); remaking window.",
574 (uint)window->visual->visAttribs, (uint)context->visual->visAttribs);
575 /*
576 * XXX have to revisit this issue!!!
577 *
578 * But for now we destroy the current window
579 * and re-create it with the context's visual abilities
580 */
581 renderspu_SystemDestroyWindow(window);
582 renderspu_SystemCreateWindow(context->visual, window->visible,
583 window);
584 }
585
586 /* This is the normal case: rendering to the render SPU's own window */
587 result = renderspuWindowAttachContext(window, window->window,
588 context);
589 /* XXX this is a total hack to work around an NVIDIA driver bug */
590 if(render_spu.self.GetFloatv && context->haveWindowPosARB)
591 {
592 GLfloat f[4];
593 render_spu.self.GetFloatv(GL_CURRENT_RASTER_POSITION, f);
594 if (!window->everCurrent || f[1] < 0.0)
595 {
596 crDebug("Render SPU: Resetting raster pos");
597 render_spu.self.WindowPos2iARB(0, 0);
598 }
599 }
600 }
601 else
602 renderspuWindowAttachContext (0, 0, 0);
603}
604
605void
606renderspu_SystemSwapBuffers(WindowInfo *window, GLint flags)
607{
608 CRASSERT(window);
609 CRASSERT(window->window);
610
611 ContextInfo *context = renderspuGetWindowContext(window);
612
613 if(!context)
614 crError("Render SPU: SwapBuffers got a null context from the window");
615
616 DEBUG_MSG_POETZSCH (("Swapped %d context %x visible: %d\n", window->id, context->context, IsWindowVisible (window->window)));
617 render_spu.ws.aglSwapBuffers(context->context);
618
619 /* This method seems called very often. To prevent the dock using all free
620 * resources we update the dock only two times per second. */
621 uint64_t curTS = RTTimeMilliTS();
622 if ((curTS - gDockUpdateTS) > 500)
623 {
624 OSStatus status = noErr;
625 /* Send a event to the main thread, cause some function of Carbon aren't
626 * thread safe */
627 EventRef evt;
628 status = CreateEvent(NULL, kEventClassVBox, kEventVBoxUpdateDock, 0, kEventAttributeNone, &evt);
629 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: CreateEvent Failed");
630 status = PostEventToQueue(GetMainEventQueue(), evt, kEventPriorityStandard);
631 CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU: PostEventToQueue Failed");
632
633 gDockUpdateTS = curTS;
634 }
635}
636
637void renderspu_SystemWindowVisibleRegion(WindowInfo *window, GLint cRects, GLint* pRects)
638{
639 CRASSERT(window);
640 CRASSERT(window->window);
641
642 ContextInfo *c;
643 c = renderspuGetWindowContext (window);
644 if (c &&
645 c->context)
646 {
647 int i;
648 /* Create some temporary regions */
649 RgnHandle rgn = NewRgn();
650 SetEmptyRgn (rgn);
651 RgnHandle tmpRgn = NewRgn();
652 for (i=0; i<cRects; ++i)
653 {
654 SetRectRgn (tmpRgn,
655 pRects[4*i] , pRects[4*i+1],
656 pRects[4*i+2], pRects[4*i+3]);
657 UnionRgn (rgn, tmpRgn, rgn);
658 }
659 DisposeRgn (tmpRgn);
660
661 GLboolean result = true;
662 /* Set the clip region to the context */
663 result = render_spu.ws.aglSetInteger(c->context, AGL_CLIP_REGION, (const GLint*)rgn);
664 CHECK_AGL_RC (result, "Render SPU: SetInteger Failed");
665 result = render_spu.ws.aglEnable(c->context, AGL_CLIP_REGION);
666 CHECK_AGL_RC (result, "Render SPU: Enable Failed");
667 /* Clear the region structure */
668 DisposeRgn (rgn);
669 }
670}
671
672GLboolean
673renderspu_SystemVBoxCreateWindow(VisualInfo *visual, GLboolean showIt,
674 WindowInfo *window)
675{
676 CRASSERT(visual);
677 CRASSERT(window);
678
679 WindowAttributes winAttr = kWindowNoShadowAttribute | kWindowCompositingAttribute | kWindowIgnoreClicksAttribute | kWindowStandardHandlerAttribute | kWindowLiveResizeAttribute;
680 WindowClass winClass = kOverlayWindowClass;
681 Rect windowRect;
682 OSStatus status = noErr;
683
684 window->visual = visual;
685 window->nativeWindow = NULL;
686
687 if(window->window && IsValidWindowPtr(window->window))
688 {
689 EventRef evt;
690 status = CreateEvent(NULL, kEventClassVBox, kEventVBoxDisposeWindow, 0, kEventAttributeNone, &evt);
691 CHECK_CARBON_RC_RETURN (status, "Render SPU: CreateEvent Failed", false);
692 status = SetEventParameter(evt, kEventParamWindowRef, typeWindowRef, sizeof (window->window), &window->window);
693 CHECK_CARBON_RC_RETURN (status, "Render SPU: SetEventParameter Failed", false);
694 status = SendEventToEventTarget (evt, GetWindowEventTarget (HIViewGetWindow ((HIViewRef)render_spu_parent_window_id)));
695 CHECK_CARBON_RC_RETURN (status, "Render SPU: PostEventToQueue Failed", false);
696 }
697
698 windowRect.left = window->x;
699 windowRect.top = window->y;
700 windowRect.right = window->x + window->width;
701 windowRect.bottom = window->y + window->height;
702
703 status = CreateNewWindow(winClass, winAttr, &windowRect, &window->window);
704 CHECK_CARBON_RC_RETURN (status, "Render SPU: CreateNewWindow Failed", GL_FALSE);
705
706 /* We set a title for debugging purposes */
707 CFStringRef title_string;
708 title_string = CFStringCreateWithCStringNoCopy(NULL, window->title,
709 kCFStringEncodingMacRoman, NULL);
710 SetWindowTitleWithCFString(window->window, title_string);
711 CFRelease(title_string);
712
713 /* We need grouping so create a master group for this & all following
714 * windows & one group for the parent. */
715 if(!gMasterGroup || !gParentGroup)
716 {
717 status = CreateWindowGroup(kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrSharedActivation | kWindowGroupAttrHideOnCollapse | kWindowGroupAttrFixedLevel, &gMasterGroup);
718 CHECK_CARBON_RC_RETURN (status, "Render SPU: CreateWindowGroup Failed", GL_FALSE);
719 status = CreateWindowGroup(kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrSharedActivation | kWindowGroupAttrHideOnCollapse | kWindowGroupAttrFixedLevel, &gParentGroup);
720 CHECK_CARBON_RC_RETURN (status, "Render SPU: CreateWindowGroup Failed", GL_FALSE);
721 /* Make the correct z-layering */
722 SendWindowGroupBehind (gParentGroup, gMasterGroup);
723 /* and set the gParentGroup as parent for gMasterGroup. */
724#ifdef __LP64__ /** @todo port to 64-bit darwin. */
725#else
726 SetWindowGroupParent (gMasterGroup, gParentGroup);
727#endif
728 }
729
730 /* The parent has to be in its own group */
731 WindowRef parent = NULL;
732 if (render_spu_parent_window_id)
733 {
734 parent = HIViewGetWindow ((HIViewRef)render_spu_parent_window_id);
735 SetWindowGroup (parent, gParentGroup);
736 }
737 /* Add the new window to the master group */
738 SetWindowGroup(window->window, gMasterGroup);
739
740 /* Own handler needed? */
741 {
742 /* Even though there are still issues with the windows themselves,
743 install the event handlers */
744 EventTypeSpec event_list[] = { {kEventClassWindow, kEventWindowClose} };
745
746 window->event_handler = NewEventHandlerUPP( windowEvtHndlr );
747
748 /*InstallWindowEventHandler(window->window, window->event_handler,
749 GetEventTypeCount(event_list), event_list,
750 NULL, NULL);*/
751 }
752
753 /* This will be initialized on the first attempt to attach the global
754 * context to this new window */
755 window->bufferName = -1;
756 window->dummyContext = NULL;
757
758 if(showIt)
759 renderspu_SystemShowWindow(window, GL_TRUE);
760
761 crDebug("Render SPU: actual window (x, y, width, height): %d, %d, %d, %d",
762 window->x, window->y, window->width, window->height);
763
764 return GL_TRUE;
765}
766
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette