Changeset 57131 in vbox for trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m
- Timestamp:
- Jul 30, 2015 3:13:06 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m
r56419 r57131 78 78 { 79 79 @private 80 NSView *m_pParentView; 81 /** Set if the buffers needs clearing. */ 82 bool m_fClear; 80 /** This points to the parent view, if there is one. If there isn't a parent 81 * the view will be hidden and never used for displaying stuff. We only have 82 * one visible context per guest screen that is visible to the user and 83 * subject to buffer swapping. */ 84 NSView *m_pParentView; 85 /** Indicates that buffers (back+front) needs clearing before use because 86 * the view changed size. There are two buffers, so this is set to two 87 * each time when the view area increases. */ 88 uint32_t m_cClears; 89 /** Set if the OpenGL context needs updating after a resize. */ 90 bool m_fUpdateCtx; 83 91 84 92 #ifndef USE_NSOPENGLVIEW … … 87 95 #endif 88 96 89 /* Position/Size tracking */ 90 NSPoint m_Pos; 91 NSSize m_Size; 92 93 /** This is necessary for clipping on the root window */ 94 NSRect m_RootRect; 97 /** The desired view position relative to super. */ 98 NSPoint m_Pos; 99 /** The desired view size. */ 100 NSSize m_Size; 95 101 } 96 102 + (void)createViewAndContext:(VMSVGA3DCreateViewAndContext *)pParams; 97 103 - (id)initWithFrameAndFormat:(NSRect)frame parentView:(NSView*)pparentView pixelFormat:(NSOpenGLPixelFormat *)pFmt; 98 - (void)setPos:(NSPoint)pos; 99 - (void)setSize:(NSSize)size; 104 - (void)vboxSetPos:(NSPoint)pos; 105 - (void)vboxSetSize:(NSSize)size; 106 - (void)vboxReshapePerform; 100 107 - (void)vboxReshape; 108 #if 0 // doesn't work or isn't needed :/ 109 - (void)vboxFrameDidChange; 110 - (BOOL)postsFrameChangedNotifications; 111 #endif 112 - (void)vboxRemoveFromSuperviewAndHide; 101 113 - (void)vboxClearBuffers; 114 - (void)vboxUpdateCtxIfNecessary; 115 - (void)vboxClearBackBufferIfNecessary; 102 116 - (NSOpenGLContext *)makeCurrentGLContext; 103 117 - (void)restoreSavedGLContext:(NSOpenGLContext *)pSavedCtx; … … 191 205 { 192 206 /* 193 * Attach the view to the parent .207 * Attach the view to the parent if we have one. Otherwise make sure its invisible. 194 208 */ 195 [pParams->pParentView addSubview:pView]; 209 if (pParams->pParentView) 210 [pParams->pParentView addSubview:pView]; 211 else 212 [pView setHidden:YES]; 196 213 197 214 /* 198 215 * Resize and return. 199 216 */ 200 //[pView setSize:Frame.size];217 //[pView vboxSetSize:Frame.size]; 201 218 202 219 NSOpenGLContext *pSavedCtx = [pView makeCurrentGLContext]; … … 208 225 x = 0; [pCtx setValues:&x forParameter:NSOpenGLCPSurfaceOpacity]; 209 226 210 [pView setHidden:NO]; 227 if (pParams->pParentView) 228 [pView setHidden:NO]; 229 else 230 [pView setHidden:YES]; 211 231 212 232 [pView restoreSavedGLContext:pSavedCtx]; … … 217 237 218 238 [pFmt release]; 239 240 #if 0 // doesn't work or isn't needed :/ 241 /* 242 * Get notifications when we're moved... 243 */ 244 if (pParams->pParentView) 245 { 246 [[NSNotificationCenter defaultCenter] addObserver:self 247 selector:@selector(vboxFrameDidChange) 248 name:NSViewFrameDidChangeNotification 249 object:self]; 250 } 251 #endif 252 219 253 LogFlow(("OvlView createViewAndContext: returns successfully\n")); 220 254 return; … … 239 273 m_Pos = NSZeroPoint; 240 274 m_Size = frame.size; 241 m_RootRect = NSMakeRect(0, 0, m_Size.width, m_Size.height); 275 m_cClears = 2; 276 m_fUpdateCtx = true; 242 277 243 278 #ifdef USE_NSOPENGLVIEW … … 248 283 if (self) 249 284 { 250 self.autoresizingMask = NSViewMinXMargin | NSViewMaxXMargin | NSViewMinYMargin | NSViewMaxYMargin; 285 //self.autoresizingMask = NSViewMinXMargin | NSViewMaxXMargin | NSViewMinYMargin | NSViewMaxYMargin; 286 self.autoresizingMask = NSViewNotSizable; 251 287 } 252 288 LogFlow(("OvlView(%p) initWithFrameAndFormat: returns %p\n", (void *)self, (void *)self)); … … 275 311 276 312 277 - (void) setPos:(NSPoint)pos278 { 279 Log(("OvlView(%p) setPos: (%d,%d)\n", (void *)self, (int)pos.x, (int)pos.y));313 - (void)vboxSetPos:(NSPoint)pos 314 { 315 Log(("OvlView(%p) vboxSetPos: (%d,%d)\n", (void *)self, (int)pos.x, (int)pos.y)); 280 316 281 317 m_Pos = pos; 282 318 [self vboxReshape]; 283 319 284 LogFlow(("OvlView(%p) setPos: returns\n", (void *)self));285 } 286 287 288 - (void) setSize:(NSSize)size289 { 290 Log(("OvlView(%p) setSize: (%d,%d):\n", (void *)self, (int)size.width, (int)size.height));320 LogFlow(("OvlView(%p) vboxSetPos: returns\n", (void *)self)); 321 } 322 323 324 - (void)vboxSetSize:(NSSize)size 325 { 326 Log(("OvlView(%p) vboxSetSize: (%d,%d):\n", (void *)self, (int)size.width, (int)size.height)); 291 327 m_Size = size; 292 328 [self vboxReshape]; 293 LogFlow(("OvlView(%p) setSize: returns\n", (void *)self));329 LogFlow(("OvlView(%p) vboxSetSize: returns\n", (void *)self)); 294 330 } 295 331 … … 305 341 NSOpenGLContext *pSavedCtx = [self makeCurrentGLContext]; 306 342 343 /* Clear errors. */ 344 GLenum rc; 345 while ((rc = glGetError()) != GL_NO_ERROR) 346 continue; 347 348 /* Save the old buffer setting and make it GL_BACK (shall be GL_BACK already actually). */ 307 349 GLint iOldDrawBuf = GL_BACK; 308 350 glGetIntegerv(GL_DRAW_BUFFER, &iOldDrawBuf); 309 glDrawBuffer(GL_FRONT_AND_BACK); 351 glDrawBuffer(GL_BACK); 352 while ((rc = glGetError()) != GL_NO_ERROR) 353 AssertMsgFailed(("rc=%x\n", rc)); 354 355 /* Clear the current GL_BACK. */ 310 356 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 311 357 glClear(GL_COLOR_BUFFER_BIT /*|GL_DEPTH_BUFFER_BIT*/ ); 312 358 [[self openGLContext] flushBuffer]; 359 while ((rc = glGetError()) != GL_NO_ERROR) 360 AssertMsgFailed(("rc=%x\n", rc)); 361 362 /* Clear the previous GL_FRONT. */ 363 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 364 glClear(GL_COLOR_BUFFER_BIT /*|GL_DEPTH_BUFFER_BIT*/ ); 365 [[self openGLContext] flushBuffer]; 366 while ((rc = glGetError()) != GL_NO_ERROR) 367 AssertMsgFailed(("rc=%x\n", rc)); 368 369 /* We're back to the orignal back buffer now. Just restore GL_DRAW_BUFFER. */ 313 370 glDrawBuffer(iOldDrawBuf); 314 371 372 while ((rc = glGetError()) != GL_NO_ERROR) 373 AssertMsgFailed(("rc=%x\n", rc)); 374 315 375 [self restoreSavedGLContext:pSavedCtx]; 316 376 } … … 318 378 } 319 379 380 - (void)vboxUpdateCtxIfNecessary 381 { 382 if (m_fUpdateCtx) 383 { 384 Log(("OvlView(%p) vboxUpdateCtxIfNecessary: m_fUpdateCtx\n", (void *)self)); 385 [[self openGLContext] update]; 386 m_fUpdateCtx = false; 387 } 388 } 389 390 391 - (void)vboxClearBackBufferIfNecessary 392 { 393 #if 1 /* experiment */ 394 if (m_cClears > 0) 395 { 396 Assert(![NSThread isMainThread]); 397 Assert([self openGLContext] == [NSOpenGLContext currentContext]); 398 Log(("OvlView(%p) vboxClearBackBufferIfNecessary: m_cClears=%d\n", (void *)self, m_cClears)); 399 m_cClears--; 400 401 /* Clear errors. */ 402 GLenum rc; 403 while ((rc = glGetError()) != GL_NO_ERROR) 404 continue; 405 406 /* Save the old buffer setting and make it GL_BACK (shall be GL_BACK already actually). */ 407 GLint iOldDrawBuf = GL_BACK; 408 glGetIntegerv(GL_DRAW_BUFFER, &iOldDrawBuf); 409 if (iOldDrawBuf != GL_BACK) 410 glDrawBuffer(GL_BACK); 411 while ((rc = glGetError()) != GL_NO_ERROR) 412 AssertMsgFailed(("rc=%x\n", rc)); 413 414 /* Clear the current GL_BACK. */ 415 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 416 glClear(GL_COLOR_BUFFER_BIT /*|GL_DEPTH_BUFFER_BIT*/ ); 417 while ((rc = glGetError()) != GL_NO_ERROR) 418 AssertMsgFailed(("rc=%x\n", rc)); 419 420 /* We're back to the orignal back buffer now. Just restore GL_DRAW_BUFFER. */ 421 if (iOldDrawBuf != GL_BACK) 422 glDrawBuffer(iOldDrawBuf); 423 424 while ((rc = glGetError()) != GL_NO_ERROR) 425 AssertMsgFailed(("rc=%x\n", rc)); 426 } 427 #endif 428 } 429 430 431 432 - (void)vboxReshapePerform 433 { 434 /* 435 * Change the size and position if necessary. 436 */ 437 NSRect CurFrameRect = [self frame]; 438 /** @todo conversions? */ 439 if ( m_Pos.x != CurFrameRect.origin.x 440 || m_Pos.y != CurFrameRect.origin.y) 441 { 442 LogFlow(("OvlView(%p) vboxReshapePerform: moving (%d,%d) -> (%d,%d)\n", 443 (void *)self, CurFrameRect.origin.x, CurFrameRect.origin.y, m_Pos.x, m_Pos.y)); 444 [self setFrameOrigin:m_Pos]; 445 } 446 447 if ( CurFrameRect.size.width != m_Size.width 448 || CurFrameRect.size.height != m_Size.height) 449 { 450 LogFlow(("OvlView(%p) vboxReshapePerform: resizing (%d,%d) -> (%d,%d)\n", 451 (void *)self, CurFrameRect.size.width, CurFrameRect.size.height, m_Size.width, m_Size.height)); 452 [self setFrameSize:m_Size]; 453 454 /* 455 * Schedule two clears and a context update for now. 456 * Really though, we should just clear any new surface area. 457 */ 458 m_cClears = 2; 459 } 460 m_fUpdateCtx = true; 461 LogFlow(("OvlView(%p) vboxReshapePerform: returns\n", self)); 462 } 463 320 464 321 465 - (void)vboxReshape … … 324 468 325 469 /* 326 * Not doing any complicate stuff here yet, hoping that we'll get correctly 327 * resized when the parent view changes... 470 * Resize the view. 328 471 */ 329 330 /* 331 * Tell the GL context. 332 */ 333 //[[self openGLContext] setView:self]; 334 [[self openGLContext] update]; 335 336 [self vboxClearBuffers]; 472 if ([NSThread isMainThread]) 473 [self vboxReshapePerform]; 474 else 475 { 476 [self performSelectorOnMainThread:@selector(vboxReshapePerform) withObject:nil waitUntilDone:NO]; 477 vmsvga3dCocoaServiceRunLoop(); 478 479 /* 480 * Try update the opengl context. 481 */ 482 [[self openGLContext] update]; 483 } 337 484 338 485 LogFlow(("OvlView(%p) vboxReshape: returns\n", (void *)self)); 486 } 487 488 #if 0 // doesn't work or isn't needed :/ 489 - (void)vboxFrameDidChange 490 { 491 LogFlow(("OvlView(%p) vboxFrameDidChange:\n", (void *)self)); 492 } 493 494 - (BOOL)postsFrameChangedNotifications 495 { 496 LogFlow(("OvlView(%p) postsFrameChangedNotifications:\n", (void *)self)); 497 return YES; 498 } 499 #endif 500 501 /** 502 * Removes the view from the parent, if it has one, and makes sure it's hidden. 503 * 504 * This is callbed before destroying it. 505 */ 506 - (void)vboxRemoveFromSuperviewAndHide 507 { 508 LogFlow(("OvlView(%p) vboxRemoveFromSuperviewAndHide:\n", (void *)self)); 509 if (m_pParentView) 510 { 511 [self removeFromSuperview]; 512 [self setHidden:YES]; 513 [[NSNotificationCenter defaultCenter] removeObserver:self]; 514 } 339 515 } 340 516 … … 419 595 */ 420 596 597 /** @todo do we need this? */ 421 598 -(void)viewDidMoveToWindow 422 599 { … … 443 620 - (void)drawRect:(NSRect)rect 444 621 { 445 if (m_fClear)446 {447 m_fClear = false;448 [self vboxClearBuffers];449 }622 // if (m_fClear) 623 // { 624 // m_fClear = false; 625 // [self vboxClearBuffers]; 626 // } 450 627 } 451 628 … … 470 647 471 648 649 /** 650 * Document me later. 651 * 652 * @param pParentView The parent view if this is a context we'll be 653 * presenting to. 654 */ 472 655 VMSVGA3DCOCOA_DECL(bool) vmsvga3dCocoaCreateViewAndContext(NativeNSViewRef *ppView, NativeNSOpenGLContextRef *ppCtx, 473 656 NativeNSViewRef pParentView, uint32_t cx, uint32_t cy, … … 513 696 514 697 /* The view */ 515 [ pView removeFromSuperview];516 [pView setHidden: YES]; 698 [(VMSVGA3DOverlayView *)pView vboxRemoveFromSuperviewAndHide]; 699 517 700 Log(("vmsvga3dCocoaDestroyViewAndContext: view %p ref count=%d\n", (void *)pView, [pView retainCount])); 518 701 [pView release]; … … 527 710 528 711 712 /** @note Not currently used. */ 529 713 VMSVGA3DCOCOA_DECL(void) vmsvga3dCocoaViewSetPosition(NativeNSViewRef pView, NativeNSViewRef pParentView, int x, int y) 530 714 { … … 532 716 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; 533 717 534 [(VMSVGA3DOverlayView *)pView setPos:NSMakePoint(x, y)];718 [(VMSVGA3DOverlayView *)pView vboxSetPos:NSMakePoint(x, y)]; 535 719 536 720 [pPool release]; … … 545 729 VMSVGA3DOverlayView *pOverlayView = (VMSVGA3DOverlayView *)pView; 546 730 547 [pOverlayView setSize:NSMakeSize(cx, cy)];731 [pOverlayView vboxSetSize:NSMakeSize(cx, cy)]; 548 732 549 733 [pPool release]; … … 554 738 void vmsvga3dCocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx) 555 739 { 556 LogFlow(("vmsvga3dCocoaView SetSize: pView=%p, pCtx=%p\n", (void*)pView, (void*)pCtx));740 LogFlow(("vmsvga3dCocoaViewMakeCurrentContext: pView=%p, pCtx=%p\n", (void*)pView, (void*)pCtx)); 557 741 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; 558 742 VMSVGA3DOverlayView *pOverlayView = (VMSVGA3DOverlayView *)pView; … … 569 753 AssertRelease([pOverlayView openGLContext] == pCtx); 570 754 [pCtx makeCurrentContext]; 755 [pOverlayView vboxUpdateCtxIfNecessary]; 571 756 } 572 757 else … … 582 767 LogFlow(("vmsvga3dCocoaSwapBuffers: pView=%p, pCtx=%p\n", (void*)pView, (void*)pCtx)); 583 768 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; 769 VMSVGA3DOverlayView *pMyView = (VMSVGA3DOverlayView *)pView; 584 770 585 771 #ifndef USE_NSOPENGLVIEW 586 772 /* Hack alert! setView fails early on so call openGLContext to try again. */ 587 VMSVGA3DOverlayView *pMyView = (VMSVGA3DOverlayView *)pView;588 773 if ([pCtx view] == NULL) 589 774 [pMyView openGLContext]; 590 #elif defined(RT_STRICT)591 NSOpenGLView *pMyView = (NSOpenGLView *)pView;592 775 #endif 593 776 … … 600 783 vmsvga3dCocoaServiceRunLoop(); 601 784 785 /* If buffer clearing or/and context updates are pending, execute that now. */ 786 [pMyView vboxUpdateCtxIfNecessary]; 787 [pMyView vboxClearBackBufferIfNecessary]; 788 602 789 [pPool release]; 603 790 LogFlow(("vmsvga3dCocoaSwapBuffers: returns\n"));
Note:
See TracChangeset
for help on using the changeset viewer.