VirtualBox

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

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

crOpenGL-OSX: more fixes

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