Changeset 55840 in vbox for trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m
- Timestamp:
- May 13, 2015 9:36:04 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m
r54638 r55840 18 18 */ 19 19 20 /******************************************************************************* 21 * Header Files * 22 *******************************************************************************/ 23 #define LOG_GROUP LOG_GROUP_DEV_VMSVGA 20 24 #include "DevVGA-SVGA3d-cocoa.h" 21 25 #import <Cocoa/Cocoa.h> … … 24 28 #include <iprt/thread.h> 25 29 #include <iprt/assert.h> 26 27 /* Debug macros */ 28 #if 0 /*def DEBUG_VERBOSE*/ 29 /*# error "should be disabled!"*/ 30 # define DEBUG_INFO(text) do { \ 31 crWarning text ; \ 32 Assert(0); \ 33 } while (0) 34 35 # define DEBUG_MSG(text) \ 36 printf text 37 38 # define DEBUG_WARN(text) do { \ 39 crWarning text ; \ 40 Assert(0); \ 41 } while (0) 42 43 # define DEBUG_MSG_1(text) \ 44 DEBUG_MSG(text) 45 46 # define DEBUG_FUNC_ENTER() \ 47 int cchDebugFuncEnter = printf("==>%s\n", __PRETTY_FUNCTION__) 48 49 #define DEBUG_FUNC_LEAVE() do { \ 50 DEBUG_MSG(("<==%s\n", __PRETTY_FUNCTION__)); \ 51 } while (0) 52 53 #define DEBUG_FUNC_RET(valuefmtnl) do { \ 54 DEBUG_MSG(("<==%s returns", __PRETTY_FUNCTION__)); \ 55 DEBUG_MSG(valuefmtnl); \ 56 } while (0) 57 30 #include <iprt/string.h> 31 #include <VBox/log.h> 32 33 34 /******************************************************************************* 35 * Defined Constants And Macros * 36 *******************************************************************************/ 37 /** @def USE_NSOPENGLVIEW 38 * Define this to experiment with using NSOpenGLView instead 39 * of NSView. There are transparency issues with the former, 40 * so for the time being we're using the latter. */ 41 #if 0 42 #define USE_NSOPENGLVIEW 43 #endif 44 45 46 /******************************************************************************* 47 * Structures and Typedefs * 48 *******************************************************************************/ 49 /** 50 * Argument package for doing this on the main thread. 51 */ 52 @interface VMSVGA3DCreateViewAndContext : NSObject 53 { 54 @public 55 /* in */ 56 NativeNSViewRef pParentView; 57 uint32_t cx; 58 uint32_t cy; 59 NativeNSOpenGLContextRef pSharedCtx; 60 bool fOtherProfile; 61 62 /* out */ 63 NativeNSViewRef pView; 64 NativeNSOpenGLContextRef pCtx; 65 } 66 @end 67 68 69 /** 70 * The overlay view. 71 */ 72 @interface VMSVGA3DOverlayView 73 #ifdef USE_NSOPENGLVIEW 74 : NSOpenGLView 58 75 #else 59 60 # define DEBUG_INFO(text) do { \ 61 crInfo text ; \ 62 } while (0) 63 64 # define DEBUG_MSG(text) \ 65 do {} while (0) 66 67 # define DEBUG_WARN(text) do { \ 68 crWarning text ; \ 69 } while (0) 70 71 # define DEBUG_MSG_1(text) \ 72 do {} while (0) 73 74 # define DEBUG_FUNC_ENTER() int cchDebugFuncEnter = 0 75 # define DEBUG_FUNC_LEAVE() NOREF(cchDebugFuncEnter) 76 # define DEBUG_FUNC_RET(valuefmtnl) DEBUG_FUNC_LEAVE() 77 78 #endif 79 80 # define CHECK_GL_ERROR()\ 81 do {} while (0) 82 83 84 /** Custom OpenGL context class. 85 * 86 * This implementation doesn't allow to set a view to the 87 * context, but save the view for later use. Also it saves a copy of the 88 * pixel format used to create that context for later use. */ 89 @interface VMSVGA3DOpenGLContext: NSOpenGLContext 90 { 91 @private 92 NSOpenGLPixelFormat *m_pPixelFormat; 93 NSView *m_pView; 94 } 95 - (NSOpenGLPixelFormat*)openGLPixelFormat; 96 @end 97 98 @interface VMSVGA3DOverlayView: NSView 76 : NSView 77 #endif 99 78 { 100 79 @private 101 80 NSView *m_pParentView; 102 NSWindow *m_pOverlayWin; 103 104 NSOpenGLContext *m_pGLCtx; 105 81 /** Set if the buffers needs clearing. */ 82 bool m_fClear; 83 84 #ifndef USE_NSOPENGLVIEW 85 /** The OpenGL context associated with this view. */ 86 NSOpenGLContext *m_pCtx; 87 #endif 88 106 89 /* Position/Size tracking */ 107 90 NSPoint m_Pos; … … 110 93 /** This is necessary for clipping on the root window */ 111 94 NSRect m_RootRect; 112 float m_yInvRootOffset; 113 } 114 - (id)initWithFrame:(NSRect)frame parentView:(NSView*)pparentView; 115 - (void)setGLCtx:(NSOpenGLContext*)pCtx; 116 - (NSOpenGLContext*)glCtx; 117 - (void)setOverlayWin: (NSWindow*)win; 118 - (NSWindow*)overlayWin; 95 } 96 + (void)createViewAndContext:(VMSVGA3DCreateViewAndContext *)pParams; 97 - (id)initWithFrameAndFormat:(NSRect)frame parentView:(NSView*)pparentView pixelFormat:(NSOpenGLPixelFormat *)pFmt; 119 98 - (void)setPos:(NSPoint)pos; 120 - (NSPoint)pos;121 99 - (void)setSize:(NSSize)size; 122 - (NSSize) size; 123 - (void)updateViewportCS; 124 - (void)reshape; 100 - (void)vboxReshape; 101 - (void)vboxClearBuffers; 102 - (NSOpenGLContext *)makeCurrentGLContext; 103 - (void)restoreSavedGLContext:(NSOpenGLContext *)pSavedCtx; 104 105 #ifndef USE_NSOPENGLVIEW 106 /* NSOpenGLView fakes: */ 107 - (void)setOpenGLContext:(NSOpenGLContext *)pCtx; 108 - (NSOpenGLContext *)openGLContext; 109 - (void)prepareOpenGL; 110 111 #endif 112 /* Overridden: */ 113 - (void)viewDidMoveToWindow; 114 - (void)viewDidMoveToSuperview; 115 - (void)resizeWithOldSuperviewSize:(NSSize)oldBoundsSize; 116 - (void)drawRect:(NSRect)rect; 117 125 118 @end 126 119 127 /** Helper view.128 *129 * This view is added as a sub view of the parent view to track130 * main window changes. Whenever the main window is changed131 * (which happens on fullscreen/seamless entry/exit) the overlay132 * window is informed & can add them self as a child window133 * again. */134 @class VMSVGA3DOverlayWindow;135 @interface VMSVGA3DOverlayHelperView: NSView136 {137 @private138 VMSVGA3DOverlayWindow *m_pOverlayWindow;139 }140 -(id)initWithOverlayWindow:(VMSVGA3DOverlayWindow*)pOverlayWindow;141 @end142 143 /** Custom window class.144 *145 * This is the overlay window which contains our custom NSView.146 * Its a direct child of the Qt Main window. It marks its background147 * transparent & non opaque to make clipping possible. It also disable mouse148 * events and handle frame change events of the parent view. */149 @interface VMSVGA3DOverlayWindow: NSWindow150 {151 @private152 NSView *m_pParentView;153 VMSVGA3DOverlayView *m_pOverlayView;154 VMSVGA3DOverlayHelperView *m_pOverlayHelperView;155 NSThread *m_Thread;156 }157 - (id)initWithParentView:(NSView*)pParentView overlayView:(VMSVGA3DOverlayView*)pOverlayView;158 - (void)parentWindowFrameChanged:(NSNotification *)note;159 - (void)parentWindowChanged:(NSWindow*)pWindow;160 @end161 162 163 /********************************************************************************164 *165 * VMSVGA3DOpenGLContext class implementation166 *167 ********************************************************************************/168 @implementation VMSVGA3DOpenGLContext169 170 -(id)initWithFormat:(NSOpenGLPixelFormat*)format shareContext:(NSOpenGLContext*)share171 {172 DEBUG_FUNC_ENTER();173 174 m_pPixelFormat = NULL;175 m_pView = NULL;176 177 self = [super initWithFormat:format shareContext:share];178 if (self)179 m_pPixelFormat = format;180 181 DEBUG_MSG(("OCTX(%p): init VMSVGA3DOpenGLContext\n", (void*)self));182 DEBUG_FUNC_RET(("%p\n", (void *)self));183 return self;184 }185 186 - (void)dealloc187 {188 DEBUG_FUNC_ENTER();189 DEBUG_MSG(("OCTX(%p): dealloc VMSVGA3DOpenGLContext\n", (void*)self));190 191 [m_pPixelFormat release];192 193 m_pPixelFormat = NULL;194 m_pView = NULL;195 196 [super dealloc];197 DEBUG_FUNC_LEAVE();198 }199 200 -(bool)isDoubleBuffer201 {202 DEBUG_FUNC_ENTER();203 GLint val;204 [m_pPixelFormat getValues:&val forAttribute:NSOpenGLPFADoubleBuffer forVirtualScreen:0];205 DEBUG_FUNC_RET(("%d\n", val == 1 ? YES : NO));206 return val == 1 ? YES : NO;207 }208 209 -(void)setView:(NSView*)view210 {211 DEBUG_FUNC_ENTER();212 DEBUG_MSG(("OCTX(%p): setView: new view: %p\n", (void*)self, (void*)view));213 214 m_pView = view;215 216 DEBUG_FUNC_LEAVE();217 }218 219 -(NSView*)view220 {221 DEBUG_FUNC_ENTER();222 DEBUG_FUNC_RET(("%p\n", (void *)m_pView));223 return m_pView;224 }225 226 -(void)clearDrawable227 {228 DEBUG_FUNC_ENTER();229 DEBUG_MSG(("OCTX(%p): clearDrawable\n", (void*)self));230 231 m_pView = NULL;232 [super clearDrawable];233 234 DEBUG_FUNC_LEAVE();235 }236 237 -(NSOpenGLPixelFormat*)openGLPixelFormat238 {239 DEBUG_FUNC_ENTER();240 DEBUG_FUNC_RET(("%p\n", (void *)m_pPixelFormat));241 return m_pPixelFormat;242 }243 244 @end245 246 247 248 /********************************************************************************249 *250 * VMSVGA3DOverlayHelperView class implementation251 *252 ********************************************************************************/253 @implementation VMSVGA3DOverlayHelperView254 255 -(id)initWithOverlayWindow:(VMSVGA3DOverlayWindow*)pOverlayWindow256 {257 DEBUG_FUNC_ENTER();258 259 self = [super initWithFrame:NSZeroRect];260 261 m_pOverlayWindow = pOverlayWindow;262 263 DEBUG_MSG(("OHVW(%p): init OverlayHelperView\n", (void*)self));264 DEBUG_FUNC_RET(("%p\n", (void *)self));265 return self;266 }267 268 -(void)viewDidMoveToWindow269 {270 DEBUG_FUNC_ENTER();271 DEBUG_MSG(("OHVW(%p): viewDidMoveToWindow: new win: %p\n", (void*)self, (void*)[self window]));272 273 [m_pOverlayWindow parentWindowChanged:[self window]];274 275 DEBUG_FUNC_LEAVE();276 }277 278 @end279 280 /********************************************************************************281 *282 * VMSVGA3DOverlayWindow class implementation283 *284 ********************************************************************************/285 @implementation VMSVGA3DOverlayWindow286 287 - (id)initWithParentView:(NSView*)pParentView overlayView:(VMSVGA3DOverlayView*)pOverlayView288 {289 DEBUG_FUNC_ENTER();290 NSWindow *pParentWin = nil;291 292 if((self = [super initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]))293 {294 m_pParentView = pParentView;295 m_pOverlayView = pOverlayView;296 m_Thread = [NSThread currentThread];297 298 [m_pOverlayView setOverlayWin: self];299 300 m_pOverlayHelperView = [[VMSVGA3DOverlayHelperView alloc] initWithOverlayWindow:self];301 /* Add the helper view as a child of the parent view to get notifications */302 [pParentView addSubview:m_pOverlayHelperView];303 304 /* Make sure this window is transparent */305 #ifdef SHOW_WINDOW_BACKGROUND306 /* For debugging */307 [self setBackgroundColor:[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:0.7]];308 #else309 [self setBackgroundColor:[NSColor clearColor]];310 #endif311 [self setOpaque:NO];312 [self setAlphaValue:.999];313 /* Disable mouse events for this window */314 [self setIgnoresMouseEvents:YES];315 316 pParentWin = [m_pParentView window];317 318 /* Initial set the position to the parents view top/left (Compiz fix). */319 [self setFrameOrigin:320 [pParentWin convertBaseToScreen:321 [m_pParentView convertPoint:NSZeroPoint toView:nil]]];322 323 /* Set the overlay view as our content view */324 [self setContentView:m_pOverlayView];325 326 /* Add ourself as a child to the parent views window. Note: this has to327 * be done last so that everything else is setup in328 * parentWindowChanged. */329 [pParentWin addChildWindow:self ordered:NSWindowAbove];330 }331 DEBUG_MSG(("OWIN(%p): init OverlayWindow\n", (void*)self));332 DEBUG_FUNC_RET(("%p\n", (void *)self));333 return self;334 }335 336 - (void)dealloc337 {338 DEBUG_FUNC_ENTER();339 DEBUG_MSG(("OWIN(%p): dealloc OverlayWindow\n", (void*)self));340 341 [[NSNotificationCenter defaultCenter] removeObserver:self];342 343 [m_pOverlayHelperView removeFromSuperview];344 [m_pOverlayHelperView release];345 346 [super dealloc];347 DEBUG_FUNC_LEAVE();348 }349 350 - (void)parentWindowFrameChanged:(NSNotification*)pNote351 {352 DEBUG_FUNC_ENTER();353 DEBUG_MSG(("OWIN(%p): parentWindowFrameChanged\n", (void*)self));354 355 [m_pOverlayView reshape];356 357 DEBUG_FUNC_LEAVE();358 }359 360 - (void)parentWindowChanged:(NSWindow*)pWindow361 {362 DEBUG_FUNC_ENTER();363 DEBUG_MSG(("OWIN(%p): parentWindowChanged\n", (void*)self));364 365 [[NSNotificationCenter defaultCenter] removeObserver:self];366 367 if(pWindow != nil)368 {369 /* Ask to get notifications when our parent window frame changes. */370 [[NSNotificationCenter defaultCenter]371 addObserver:self372 selector:@selector(parentWindowFrameChanged:)373 name:NSWindowDidResizeNotification374 object:pWindow];375 /* Add us self as child window */376 [pWindow addChildWindow:self ordered:NSWindowAbove];377 [m_pOverlayView reshape];378 }379 380 DEBUG_FUNC_LEAVE();381 }382 383 @end384 120 385 121 /******************************************************************************** … … 390 126 @implementation VMSVGA3DOverlayView 391 127 392 - (id)initWithFrame:(NSRect) frame parentView:(NSView*)pParentView 393 { 394 DEBUG_FUNC_ENTER(); 395 396 m_pParentView = pParentView; 397 /* Make some reasonable defaults */ 398 m_pGLCtx = nil; 399 m_Pos = NSZeroPoint; 400 m_Size = NSMakeSize(1, 1); 401 m_RootRect = NSMakeRect(0, 0, m_Size.width, m_Size.height); 402 m_yInvRootOffset = 0; 403 404 self = [super initWithFrame: frame]; 405 406 DEBUG_MSG(("OVIW(%p): init VMSVGA3DOverlayView\n", (void*)self)); 407 DEBUG_FUNC_RET(("%p\n", (void *)self)); 408 return self; 409 } 410 411 - (void)cleanupData 412 { 413 DEBUG_FUNC_ENTER(); 414 415 /*[self deleteDockTile];*/ 416 417 [self setGLCtx:nil]; 418 419 #if 0 420 if (m_pSharedGLCtx) 421 { 422 if ([m_pSharedGLCtx view] == self) 423 [m_pSharedGLCtx clearDrawable]; 424 425 [m_pSharedGLCtx release]; 426 427 m_pSharedGLCtx = nil; 428 429 CrBltTerm(m_pBlitter); 430 431 RTMemFree(m_pBlitter); 432 433 m_pBlitter = nil; 434 } 435 #endif 436 437 /*[self clearVisibleRegions];*/ 438 439 DEBUG_FUNC_LEAVE(); 440 } 441 442 - (void)dealloc 443 { 444 DEBUG_FUNC_ENTER(); 445 DEBUG_MSG(("OVIW(%p): dealloc OverlayView\n", (void*)self)); 446 447 [self cleanupData]; 448 449 [super dealloc]; 450 451 DEBUG_FUNC_LEAVE(); 452 } 453 454 455 - (void)setGLCtx:(NSOpenGLContext*)pCtx 456 { 457 DEBUG_FUNC_ENTER(); 458 459 DEBUG_MSG(("OVIW(%p): setGLCtx: new ctx: %p (old: %p)\n", (void*)self, (void*)pCtx, (void *)m_pGLCtx)); 460 if (m_pGLCtx == pCtx) 461 { 462 DEBUG_FUNC_LEAVE(); 463 return; 464 } 465 466 /* ensure the context drawable is cleared to avoid holding a reference to inexistent view */ 467 if (m_pGLCtx) 468 { 469 [m_pGLCtx clearDrawable]; 470 [m_pGLCtx release]; 471 /*[m_pGLCtx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];*/ 472 } 473 m_pGLCtx = pCtx; 474 if (pCtx) 475 [pCtx retain]; 476 477 DEBUG_FUNC_LEAVE(); 478 } 479 480 - (NSOpenGLContext*)glCtx 481 { 482 DEBUG_FUNC_ENTER(); 483 DEBUG_FUNC_RET(("%p\n", (void *)m_pGLCtx)); 484 return m_pGLCtx; 485 } 486 487 - (void)setOverlayWin:(NSWindow*)pWin 488 { 489 DEBUG_FUNC_ENTER(); 490 DEBUG_MSG(("OVIW(%p): setOverlayWin: new win: %p\n", (void*)self, (void*)pWin)); 491 m_pOverlayWin = pWin; 492 DEBUG_FUNC_LEAVE(); 493 } 494 495 - (NSWindow*)overlayWin 496 { 497 DEBUG_FUNC_ENTER(); 498 DEBUG_FUNC_RET(("%p\n", (void *)m_pOverlayWin)); 499 return m_pOverlayWin; 500 } 501 502 - (void)setPos:(NSPoint)pos 503 { 504 DEBUG_FUNC_ENTER(); 505 506 m_Pos = pos; 507 [self reshape]; 508 DEBUG_FUNC_LEAVE(); 509 } 510 511 - (NSPoint)pos 512 { 513 DEBUG_FUNC_ENTER(); 514 DEBUG_FUNC_RET(("%f,%f\n", m_Pos.x, m_Pos.y)); 515 return m_Pos; 516 } 517 518 - (void)setSize:(NSSize)size 519 { 520 DEBUG_FUNC_ENTER(); 521 m_Size = size; 522 [self reshape]; 523 DEBUG_FUNC_LEAVE(); 524 } 525 526 - (NSSize)size 527 { 528 DEBUG_FUNC_ENTER(); 529 DEBUG_FUNC_RET(("%f,%f\n", m_Size.width, m_Size.height)); 530 return m_Size; 531 } 532 533 - (void)updateViewportCS 534 { 535 DEBUG_FUNC_ENTER(); 536 DEBUG_MSG(("OVIW(%p): updateViewport\n", (void*)self)); 537 538 /* Update the viewport for our OpenGL view */ 539 /* [m_pSharedGLCtx update]; */ 540 541 /* Clear background to transparent */ 542 /* glClearColor(0.0f, 0.0f, 0.0f, 0.0f);*/ 543 DEBUG_FUNC_LEAVE(); 544 } 545 546 - (void)reshape 547 { 548 DEBUG_FUNC_ENTER(); 549 NSRect parentFrame = NSZeroRect; 550 NSPoint parentPos = NSZeroPoint; 551 NSPoint childPos = NSZeroPoint; 552 NSRect childFrame = NSZeroRect; 553 NSRect newFrame = NSZeroRect; 554 555 DEBUG_MSG(("OVIW(%p): reshape\n", (void*)self)); 556 557 /* Getting the right screen coordinates of the parents frame is a little bit 558 * complicated. */ 559 parentFrame = [m_pParentView frame]; 560 DEBUG_MSG(("FIXED parentFrame [%f:%f], [%f:%f]\n", parentFrame.origin.x, parentFrame.origin.y, parentFrame.size.width, parentFrame.size.height)); 561 parentPos = [[m_pParentView window] convertBaseToScreen:[[m_pParentView superview] convertPointToBase:NSMakePoint(parentFrame.origin.x, parentFrame.origin.y + parentFrame.size.height)]]; 562 parentFrame.origin.x = parentPos.x; 563 parentFrame.origin.y = parentPos.y; 564 565 /* Calculate the new screen coordinates of the overlay window. */ 566 childPos = NSMakePoint(m_Pos.x, m_Pos.y + m_Size.height); 567 childPos = [[m_pParentView window] convertBaseToScreen:[[m_pParentView superview] convertPointToBase:childPos]]; 568 DEBUG_MSG(("FIXED childPos(screen) [%f:%f]\n", childPos.x, childPos.y)); 569 570 /* Make a frame out of it. */ 571 childFrame = NSMakeRect(childPos.x, childPos.y, m_Size.width, m_Size.height); 572 DEBUG_MSG(("FIXED childFrame [%f:%f], [%f:%f]\n", childFrame.origin.x, childFrame.origin.y, childFrame.size.width, childFrame.size.height)); 573 574 /* We have to make sure that the overlay window will not be displayed out 575 * of the parent window. So intersect both frames & use the result as the new 576 * frame for the window. */ 577 newFrame = NSIntersectionRect(parentFrame, childFrame); 578 579 DEBUG_MSG(("[%p]: parentFrame pos[%f : %f] size[%f : %f]\n", 580 (void*)self, 581 parentFrame.origin.x, parentFrame.origin.y, 582 parentFrame.size.width, parentFrame.size.height)); 583 DEBUG_MSG(("[%p]: childFrame pos[%f : %f] size[%f : %f]\n", 584 (void*)self, 585 childFrame.origin.x, childFrame.origin.y, 586 childFrame.size.width, childFrame.size.height)); 587 588 DEBUG_MSG(("[%p]: newFrame pos[%f : %f] size[%f : %f]\n", 589 (void*)self, 590 newFrame.origin.x, newFrame.origin.y, 591 newFrame.size.width, newFrame.size.height)); 592 593 /* Later we have to correct the texture position in the case the window is 594 * out of the parents window frame. So save the shift values for later use. */ 595 m_RootRect.origin.x = newFrame.origin.x - childFrame.origin.x; 596 m_RootRect.origin.y = childFrame.size.height + childFrame.origin.y - (newFrame.size.height + newFrame.origin.y); 597 m_RootRect.size = newFrame.size; 598 m_yInvRootOffset = newFrame.origin.y - childFrame.origin.y; 599 600 DEBUG_MSG(("[%p]: m_RootRect pos[%f : %f] size[%f : %f]\n", 601 (void*)self, 602 m_RootRect.origin.x, m_RootRect.origin.y, 603 m_RootRect.size.width, m_RootRect.size.height)); 604 605 /* Set the new frame. */ 606 [[self window] setFrame:newFrame display:YES]; 607 608 #if 0 609 /* Make sure the context is updated according */ 610 /* [self updateViewport]; */ 611 if (m_pSharedGLCtx) 612 { 613 VBOX_CR_RENDER_CTX_INFO CtxInfo; 614 vboxCtxEnter(m_pSharedGLCtx, &CtxInfo); 615 616 [self updateViewportCS]; 617 618 vboxCtxLeave(&CtxInfo); 619 } 620 #endif 621 DEBUG_FUNC_LEAVE(); 622 } 623 624 @end 625 626 627 void vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLContextRef pShareCtx, bool fOtherProfile) 628 { 629 DEBUG_FUNC_ENTER(); 128 129 + (void)createViewAndContext:(VMSVGA3DCreateViewAndContext *)pParams 130 { 131 LogFlow(("OvlWin createViewAndContext:\n")); 132 133 /* 134 * Create a pixel format. 135 */ 630 136 NSOpenGLPixelFormat *pFmt = nil; 631 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];632 137 633 138 // Consider to remove it and check if it's harmless. … … 638 143 NSOpenGLPFAAccelerated, 639 144 NSOpenGLPFADoubleBuffer, 145 NSOpenGLPFABackingStore, 640 146 NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)24, 641 147 NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)8, … … 643 149 0 644 150 }; 645 attribs[1] = fOtherProfile ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy; 646 647 /* Choose a pixel format */ 151 attribs[1] = pParams->fOtherProfile ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy; 648 152 pFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; 649 153 if (pFmt) 650 154 { 651 *ppCtx = [[VMSVGA3DOpenGLContext alloc] initWithFormat:pFmt shareContext:pShareCtx]; 652 DEBUG_MSG(("New context %p\n", (void *)*ppCtx)); 155 /* 156 * Create a new view. 157 */ 158 NSRect Frame; 159 Frame.origin.x = 0; 160 Frame.origin.y = 0; 161 Frame.size.width = pParams->cx < _1M ? pParams->cx : 0; 162 Frame.size.height = pParams->cy < _1M ? pParams->cy : 0; 163 VMSVGA3DOverlayView *pView = [[VMSVGA3DOverlayView alloc] initWithFrameAndFormat:Frame 164 parentView:pParams->pParentView 165 pixelFormat:pFmt]; 166 if (pView) 167 { 168 /* 169 * If we have no shared GL context, we use the one that NSOpenGLView create. Otherwise, 170 * we replace it. (If we don't call openGLContext, it won't yet have been instantiated, 171 * so there is no unecessary contexts created here when pSharedCtx != NULL.) 172 */ 173 NSOpenGLContext *pCtx; 174 #ifdef USE_NSOPENGLVIEW 175 if (!pParams->pSharedCtx) 176 pCtx = [pView openGLContext]; 177 else 178 #endif 179 { 180 pCtx = [[NSOpenGLContext alloc] initWithFormat:pFmt shareContext: pParams->pSharedCtx]; 181 if (pCtx) 182 { 183 [pView setOpenGLContext:pCtx]; 184 [pCtx setView:pView]; 185 #ifdef USE_NSOPENGLVIEW 186 Assert([pCtx view] == pView); 187 #endif 188 } 189 } 190 if (pCtx) 191 { 192 /* 193 * Attach the view to the parent. 194 */ 195 [pParams->pParentView addSubview:pView]; 196 197 /* 198 * Resize and return. 199 */ 200 //[pView setSize:Frame.size]; 201 202 NSOpenGLContext *pSavedCtx = [pView makeCurrentGLContext]; 203 204 [pView prepareOpenGL]; 205 GLint x; 206 //x = 0; [pCtx setValues:&x forParameter:NSOpenGLCPSwapInterval]; 207 //x = 1; [pCtx setValues:&x forParameter:NSOpenGLCPSurfaceOrder]; 208 x = 0; [pCtx setValues:&x forParameter:NSOpenGLCPSurfaceOpacity]; 209 210 [pView setHidden:NO]; 211 212 [pView restoreSavedGLContext:pSavedCtx]; 213 214 pParams->pView = pView; 215 pParams->pCtx = pCtx; 216 [pCtx retain]; //?? 217 218 [pFmt release]; 219 LogFlow(("OvlWin createViewAndContext: returns successfully\n")); 220 return; 221 } 222 [pView release]; 223 } 224 [pFmt release]; 653 225 } 654 226 else 655 {656 227 AssertFailed(); 657 *ppCtx = NULL; 228 229 LogFlow(("OvlWin createViewAndContext: returns failure\n")); 230 return; 231 } 232 233 - (id)initWithFrameAndFormat:(NSRect) frame parentView:(NSView*)pParentView pixelFormat:(NSOpenGLPixelFormat *)pFmt 234 { 235 LogFlow(("OvlWin(%p) initWithFrameAndFormat:\n", (void *)self)); 236 237 m_pParentView = pParentView; 238 /* Make some reasonable defaults */ 239 m_Pos = NSZeroPoint; 240 m_Size = frame.size; 241 m_RootRect = NSMakeRect(0, 0, m_Size.width, m_Size.height); 242 243 #ifdef USE_NSOPENGLVIEW 244 self = [super initWithFrame:frame pixelFormat:pFmt]; 245 #else 246 self = [super initWithFrame:frame]; 247 #endif 248 if (self) 249 { 250 self.autoresizingMask = NSViewMinXMargin | NSViewMaxXMargin | NSViewMinYMargin | NSViewMaxYMargin; 251 } 252 LogFlow(("OvlWin(%p) initWithFrameAndFormat: returns %p\n", (void *)self, (void *)self)); 253 return self; 254 } 255 256 - (void)dealloc 257 { 258 LogFlow(("OvlWin(%p) dealloc:\n", (void *)self)); 259 260 #ifdef USE_NSOPENGLVIEW 261 [[self openGLContext] clearDrawable]; 262 #else 263 if (m_pCtx) 264 { 265 [m_pCtx clearDrawable]; 266 [m_pCtx release]; 267 m_pCtx = nil; 268 } 269 #endif 270 271 [super dealloc]; 272 273 LogFlow(("OvlWin(%p) dealloc: returns\n", (void *)self)); 274 } 275 276 277 - (void)setPos:(NSPoint)pos 278 { 279 Log(("OvlWin(%p) setPos: (%d,%d)\n", (void *)self, (int)pos.x, (int)pos.y)); 280 281 m_Pos = pos; 282 [self vboxReshape]; 283 284 LogFlow(("OvlWin(%p) setPos: returns\n", (void *)self)); 285 } 286 287 288 - (void)setSize:(NSSize)size 289 { 290 Log(("OvlWin(%p) setSize: (%d,%d):\n", (void *)self, (int)size.width, (int)size.height)); 291 m_Size = size; 292 [self vboxReshape]; 293 LogFlow(("OvlWin(%p) setSize: returns\n", (void *)self)); 294 } 295 296 297 - (void)vboxClearBuffers 298 { 299 #if 1 /* experiment */ 300 if ([NSThread isMainThread]) 301 Log(("OvlWin(%p) vboxClearBuffers: skip, main thread\n", (void *)self)); 302 else 303 { 304 Log(("OvlWin(%p) vboxClearBuffers: clears\n", (void *)self)); 305 NSOpenGLContext *pSavedCtx = [self makeCurrentGLContext]; 306 307 GLint iOldDrawBuf = GL_BACK; 308 glGetIntegerv(GL_DRAW_BUFFER, &iOldDrawBuf); 309 glDrawBuffer(GL_FRONT_AND_BACK); 310 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 311 glClear(GL_COLOR_BUFFER_BIT /*|GL_DEPTH_BUFFER_BIT*/ ); 312 [[self openGLContext] flushBuffer]; 313 glDrawBuffer(iOldDrawBuf); 314 315 [self restoreSavedGLContext:pSavedCtx]; 316 } 317 #endif 318 } 319 320 321 - (void)vboxReshape 322 { 323 LogFlow(("OvlWin(%p) vboxReshape:\n", (void *)self)); 324 325 /* 326 * Not doing any complicate stuff here yet, hoping that we'll get correctly 327 * resized when the parent view changes... 328 */ 329 330 /* 331 * Tell the GL context. 332 */ 333 //[[self openGLContext] setView:self]; 334 [[self openGLContext] update]; 335 336 [self vboxClearBuffers]; 337 338 LogFlow(("OvlWin(%p) vboxReshape: returns\n", (void *)self)); 339 } 340 341 342 /** 343 * Changes to the OpenGL context associated with the view. 344 * @returns Previous OpenGL context. 345 */ 346 - (NSOpenGLContext *)makeCurrentGLContext 347 { 348 NSOpenGLContext *pSavedCtx = [NSOpenGLContext currentContext]; 349 350 /* Always flush before changing. glXMakeCurrent and wglMakeCurrent does this 351 implicitly, seemingly NSOpenGLContext::makeCurrentContext doesn't. */ 352 if (pSavedCtx != nil) 353 glFlush(); 354 355 [[self openGLContext] makeCurrentContext]; 356 return pSavedCtx; 357 } 358 359 360 /** 361 * Restores the previous OpenGL context after 362 * makeCurrentGLContext. 363 * 364 * @param pSavedCtx The makeCurrentGLContext return value. 365 */ 366 - (void)restoreSavedGLContext:(NSOpenGLContext *)pSavedCtx 367 { 368 /* Always flush before changing. glXMakeCurrent and wglMakeCurrent does this 369 implicitly, seemingly NSOpenGLContext::makeCurrentContext doesn't. */ 370 glFlush(); 371 372 if (pSavedCtx) 373 [pSavedCtx makeCurrentContext]; 374 else 375 [NSOpenGLContext clearCurrentContext]; 376 } 377 378 #ifndef USE_NSOPENGLVIEW 379 /* 380 * Faking NSOpenGLView interface. 381 */ 382 - (void)setOpenGLContext:(NSOpenGLContext *)pCtx 383 { 384 if (pCtx != m_pCtx) 385 { 386 if (pCtx) 387 { 388 [pCtx retain]; 389 [pCtx setView:self]; 390 /*Assert([pCtx view] == self); - setView fails early on, works later... */ 391 } 392 393 if (m_pCtx) 394 [m_pCtx release]; 395 396 m_pCtx = pCtx; 397 398 if (pCtx) 399 [pCtx update]; 400 } 401 } 402 403 - (NSOpenGLContext *)openGLContext 404 { 405 /* Stupid hack to work around setView failing early. */ 406 if (m_pCtx && [m_pCtx view] != self) 407 [m_pCtx setView:self]; 408 return m_pCtx; 409 } 410 411 - (void)prepareOpenGL 412 { 413 //[m_pCtx prepareOpenGL]; 414 } 415 #endif /* USE_NSOPENGLVIEW */ 416 417 /* 418 * Overridden NSOpenGLView / NSView methods: 419 */ 420 421 -(void)viewDidMoveToWindow 422 { 423 LogFlow(("OvlView(%p) viewDidMoveToWindow: new win: %p\n", (void *)self, (void *)[self window])); 424 [super viewDidMoveToWindow]; 425 [self vboxReshape]; 426 } 427 428 -(void)viewDidMoveToSuperview 429 { 430 LogFlow(("OvlView(%p) viewDidMoveToSuperview: new view: %p\n", (void *)self, (void *)[self superview])); 431 [super viewDidMoveToSuperview]; 432 [self vboxReshape]; 433 } 434 435 -(void)resizeWithOldSuperviewSize:(NSSize)oldBoundsSize 436 { 437 LogFlow(("OvlView(%p) resizeWithOldSuperviewSize: %d,%d -> %d,%d\n", (void *)self, 438 (int)oldBoundsSize.width, (int)oldBoundsSize.height, (int)[self bounds].size.width, (int)[self bounds].size.height)); 439 [super resizeWithOldSuperviewSize:oldBoundsSize]; 440 [self vboxReshape]; 441 } 442 443 - (void)drawRect:(NSRect)rect 444 { 445 if (m_fClear) 446 { 447 m_fClear = false; 448 [self vboxClearBuffers]; 449 } 450 } 451 452 @end /* VMSVGA3DOverlayView */ 453 454 @implementation VMSVGA3DCreateViewAndContext 455 @end 456 457 458 VMSVGA3DCOCOA_DECL(void) vmsvga3dCocoaServiceRunLoop(void) 459 { 460 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; 461 NSRunLoop *pRunLoop = [NSRunLoop currentRunLoop]; 462 463 if ([NSRunLoop mainRunLoop] != pRunLoop) 464 { 465 [pRunLoop runUntilDate:[NSDate distantPast]]; 658 466 } 659 467 660 468 [pPool release]; 661 662 DEBUG_FUNC_LEAVE(); 663 } 664 665 void vmsvga3dCocoaDestroyContext(NativeNSOpenGLContextRef pCtx) 666 { 667 DEBUG_FUNC_ENTER(); 469 } 470 471 472 VMSVGA3DCOCOA_DECL(bool) vmsvga3dCocoaCreateViewAndContext(NativeNSViewRef *ppView, NativeNSOpenGLContextRef *ppCtx, 473 NativeNSViewRef pParentView, uint32_t cx, uint32_t cy, 474 NativeNSOpenGLContextRef pSharedCtx, bool fOtherProfile) 475 { 476 LogFlow(("vmsvga3dCocoaCreateViewAndContext: pParentView=%d size=%d,%d pSharedCtx=%p fOtherProfile=%RTbool\n", 477 (void *)pParentView, cx, cy, (void *)pSharedCtx, fOtherProfile)); 668 478 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; 479 vmsvga3dCocoaServiceRunLoop(); 480 481 482 VMSVGA3DCreateViewAndContext *pParams = [VMSVGA3DCreateViewAndContext alloc]; 483 pParams->pParentView = pParentView; 484 pParams->cx = cx; 485 pParams->cy = cy; 486 pParams->pSharedCtx = pSharedCtx; 487 pParams->fOtherProfile = fOtherProfile; 488 pParams->pView = NULL; 489 pParams->pCtx = NULL; 490 491 [VMSVGA3DOverlayView performSelectorOnMainThread:@selector(createViewAndContext:) 492 withObject:pParams 493 waitUntilDone:YES]; 494 495 vmsvga3dCocoaServiceRunLoop(); 496 497 *ppCtx = pParams->pCtx; 498 *ppView = pParams->pView; 499 bool fRet = *ppCtx != NULL && *ppView != NULL; 500 501 [pParams release]; 502 503 [pPool release]; 504 LogFlow(("vmsvga3dCocoaDestroyContext: returns %RTbool\n", fRet)); 505 return fRet; 506 } 507 508 509 VMSVGA3DCOCOA_DECL(void) vmsvga3dCocoaDestroyViewAndContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx) 510 { 511 LogFlow(("vmsvga3dCocoaDestroyViewAndContext: pView=%p pCtx=%p\n", (void *)pView, (void *)pCtx)); 512 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; 513 514 /* The view */ 515 [pView removeFromSuperview]; 516 [pView setHidden: YES]; 517 Log(("vmsvga3dCocoaDestroyViewAndContext: view %p ref count=%d\n", (void *)pView, [pView retainCount])); 518 [pView release]; 519 520 /* The OpenGL context. */ 521 Log(("vmsvga3dCocoaDestroyViewAndContext: ctx %p ref count=%d\n", (void *)pCtx, [pView retainCount])); 669 522 [pCtx release]; 523 670 524 [pPool release]; 671 DEBUG_FUNC_LEAVE(); 672 } 673 674 void vmsvga3dCocoaCreateView(NativeNSViewRef *ppView, NativeNSViewRef pParentView) 675 { 676 DEBUG_FUNC_ENTER(); 525 LogFlow(("vmsvga3dCocoaDestroyViewAndContext: returns\n")); 526 } 527 528 529 VMSVGA3DCOCOA_DECL(void) vmsvga3dCocoaViewSetPosition(NativeNSViewRef pView, NativeNSViewRef pParentView, int x, int y) 530 { 531 LogFlow(("vmsvga3dCocoaViewSetPosition: pView=%p pParentView=%p (%d,%d)\n", (void *)pView, (void *)pParentView, x, y)); 677 532 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; 678 679 /* Create our worker view */ 680 VMSVGA3DOverlayView* pView = [[VMSVGA3DOverlayView alloc] initWithFrame:NSZeroRect parentView:pParentView]; 681 682 if (pView) 683 { 684 /* We need a real window as container for the view */ 685 [[VMSVGA3DOverlayWindow alloc] initWithParentView:pParentView overlayView:pView]; 686 /* Return the freshly created overlay view */ 687 *ppView = pView; 688 } 689 533 534 [(VMSVGA3DOverlayView *)pView setPos:NSMakePoint(x, y)]; 535 690 536 [pPool release]; 691 DEBUG_FUNC_LEAVE(); 692 } 693 694 void vmsvga3dCocoaDestroyView(NativeNSViewRef pView) 695 { 696 DEBUG_FUNC_ENTER(); 697 NSWindow *pWin = nil; 698 537 LogFlow(("vmsvga3dCocoaViewSetPosition: returns\n")); 538 } 539 540 541 VMSVGA3DCOCOA_DECL(void) vmsvga3dCocoaViewSetSize(NativeNSViewRef pView, int cx, int cy) 542 { 543 LogFlow(("vmsvga3dCocoaViewSetSize: pView=%p (%d,%d)\n", (void *)pView, cx, cy)); 699 544 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; 700 [pView setHidden: YES]; 701 702 [pWin release]; 703 [pView release]; 545 VMSVGA3DOverlayView *pOverlayView = (VMSVGA3DOverlayView *)pView; 546 547 [pOverlayView setSize:NSMakeSize(cx, cy)]; 704 548 705 549 [pPool release]; 706 DEBUG_FUNC_LEAVE(); 707 } 708 709 void vmsvga3dCocoaViewSetPosition(NativeNSViewRef pView, NativeNSViewRef pParentView, int x, int y) 710 { 711 DEBUG_FUNC_ENTER(); 550 LogFlow(("vmsvga3dCocoaViewSetSize: returns\n")); 551 } 552 553 554 void vmsvga3dCocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx) 555 { 556 LogFlow(("vmsvga3dCocoaViewSetSize: pView=%p, pCtx=%p\n", (void*)pView, (void*)pCtx)); 712 557 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; 713 714 [(VMSVGA3DOverlayView*)pView setPos:NSMakePoint(x, y)]; 715 716 [pPool release]; 717 } 718 719 void vmsvga3dCocoaViewSetSize(NativeNSViewRef pView, int w, int h) 720 { 721 DEBUG_FUNC_ENTER(); 722 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; 723 724 [(VMSVGA3DOverlayView*)pView setSize:NSMakeSize(w, h)]; 725 726 [pPool release]; 727 DEBUG_FUNC_LEAVE(); 728 } 729 730 void vmsvga3dCocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx) 731 { 732 DEBUG_FUNC_ENTER(); 733 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; 734 735 DEBUG_MSG(("cocoaViewMakeCurrentContext(%p, %p)\n", (void*)pView, (void*)pCtx)); 558 VMSVGA3DOverlayView *pOverlayView = (VMSVGA3DOverlayView *)pView; 736 559 737 560 /* Always flush before flush. glXMakeCurrent and wglMakeCurrent does this … … 740 563 glFlush(); 741 564 742 if (pView) 743 { 744 [(VMSVGA3DOverlayView*)pView setGLCtx:pCtx]; 745 /* [(VMSVGA3DOverlayView*)pView makeCurrentFBO];*/ 565 if (pOverlayView) 566 { 567 /* This must be a release assertion as we depend on the setView 568 sideeffect of the openGLContext method call. (hack alert!) */ 569 AssertRelease([pOverlayView openGLContext] == pCtx); 746 570 [pCtx makeCurrentContext]; 747 571 } 748 572 else 749 {750 573 [NSOpenGLContext clearCurrentContext]; 751 }752 574 753 575 [pPool release]; 754 DEBUG_FUNC_LEAVE(); 755 } 576 LogFlow(("vmsvga3dCocoaSwapBuffers: returns\n")); 577 } 578 756 579 757 580 void vmsvga3dCocoaSwapBuffers(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx) 758 581 { 759 DEBUG_FUNC_ENTER();582 LogFlow(("vmsvga3dCocoaSwapBuffers: pView=%p, pCtx=%p\n", (void*)pView, (void*)pCtx)); 760 583 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; 761 584 585 #ifndef USE_NSOPENGLVIEW 586 /* Hack alert! setView fails early on so call openGLContext to try again. */ 587 VMSVGA3DOverlayView *pMyView = (VMSVGA3DOverlayView *)pView; 588 if ([pCtx view] == NULL) 589 [pMyView openGLContext]; 590 #elif defined(RT_STRICT) 591 NSOpenGLView *pMyView = (NSOpenGLView *)pView; 592 #endif 593 594 Assert(pCtx == [NSOpenGLContext currentContext]); 595 Assert(pCtx == [pMyView openGLContext]); 596 AssertMsg([pCtx view] == pMyView, ("%p != %p\n", (void *)[pCtx view], (void *)pMyView)); 597 762 598 [pCtx flushBuffer]; 599 //[pView setNeedsDisplay:YES]; 600 vmsvga3dCocoaServiceRunLoop(); 763 601 764 602 [pPool release]; 765 DEBUG_FUNC_LEAVE();766 } 767 603 LogFlow(("vmsvga3dCocoaSwapBuffers: returns\n")); 604 } 605
Note:
See TracChangeset
for help on using the changeset viewer.