renderspu_cocoa_helper.m revision e64031e20c39650a7bc902a3e1aba613b9415dee
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VirtualBox OpenGL Cocoa Window System Helper implementation
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Copyright (C) 2009 Oracle Corporation
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * available from http://www.virtualbox.org. This file is free software;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * General Public License (GPL) as published by the Free Software
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include "chromium.h" /* For the visual bits of chromium */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/* Debug macros */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#define FBO 1 /* Disable this to see how the output is without the FBO in the middle of the processing chain. */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync//#define SHOW_WINDOW_BACKGROUND 1 /* Define this to see the window background even if the window is clipped */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync//#define DEBUG_VERBOSE /* Define this could get some debug info about the messages flow. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync do {} while (0)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync do {} while (0)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync }while (0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync case GL_INVALID_ENUM: errStr = RTStrDup("GL_INVALID_ENUM"); break;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync case GL_INVALID_VALUE: errStr = RTStrDup("GL_INVALID_VALUE"); break;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync case GL_INVALID_OPERATION: errStr = RTStrDup("GL_INVALID_OPERATION"); break;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync case GL_STACK_OVERFLOW: errStr = RTStrDup("GL_STACK_OVERFLOW"); break;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync case GL_STACK_UNDERFLOW: errStr = RTStrDup("GL_STACK_UNDERFLOW"); break;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync case GL_OUT_OF_MEMORY: errStr = RTStrDup("GL_OUT_OF_MEMORY"); break;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync case GL_TABLE_TOO_LARGE: errStr = RTStrDup("GL_TABLE_TOO_LARGE"); break;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync DEBUG_MSG(("%s:%d: glError %d (%s)\n", file, line, g, errStr));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync do {} while (0)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/* Custom OpenGL context class. This implementation doesn't allow to set a view
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * to the context, but save the view for later use. Also it saves a copy of the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * pixel format used to create that context for later use. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/* The custom view class. This is the main class of the cocoa OpenGL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * implementation. It manages an frame buffer object for the rendering of the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * guest applications. The guest applications render in this frame buffer which
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * is bind to an OpenGL texture. To display the guest content, an secondary
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * shared OpenGL context of the main OpenGL context is created. The secondary
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * context is marked as non opaque & the texture is displayed on an object
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * which is composed out of the several visible region rectangles. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* FBO handling */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* The corresponding dock tile view of this OpenGL view & all helper
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * members. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* For clipping */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Position/Size tracking */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* This is necessary for clipping on the root window */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync- (id)initWithFrame:(NSRect)frame thread:(RTTHREAD)aThread parentView:(NSView*)pParentView;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync- (void)setVisibleRegions:(GLint)cRects paRects:(GLint*)paRects;
* fullscreen/seamless entry/exit) the overlay window is informed & can add
@class OverlayWindow;
@end
@end
- (void)dealloc;
- (void)cleanup;
- (void)lock;
- (void)unlock;
@end
if (self)
return self;
- (void)dealloc
[super dealloc];
- (void)cleanup
- (void)lock
- (void)unlock
return YES;
[m_ThumbImage drawAtPoint:NSMakePoint(0, 0) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
return m_ThumbBitmap;
return m_ThumbImage;
@end
if (self)
return self;
- (void)dealloc
[super dealloc];
return m_pView;
return [super view];
-(void)clearDrawable
[super clearDrawable];
return m_pPixelFormat;
@end;
return self;
-(void)viewDidMoveToWindow
@end
if(self = [super initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO])
return self;
- (void)dealloc
[super dealloc];
// [m_pOverlayView performSelector:@selector(reshape) onThread:m_Thread withObject:nil waitUntilDone:YES];
// [NSTimer scheduledTimerWithTimeInterval:0.2 target:m_pOverlayView selector:@selector(reshape) userInfo:nil repeats:NO];
@end
return self;
- (void)dealloc
if (m_pGLCtx)
if (m_pSharedGLCtx)
[super dealloc];
return m_pGLCtx;
return m_pParentView;
return m_pOverlayWin;
return m_Pos;
return m_Size;
- (void)updateViewport
if (m_pSharedGLCtx)
- (void)reshape
NSPoint parentPos = [[m_pParentView window] convertBaseToScreen:[[m_pParentView superview] convertPointToBase:NSMakePoint(parentFrame.origin.x, parentFrame.origin.y + parentFrame.size.height)]];
childPos = [[m_pParentView window] convertBaseToScreen:[[m_pParentView superview] convertPointToBase:childPos]];
// printf ("sc rect: %d %d %d %d\n", (int) scrollRect.origin.x,(int) scrollRect.origin.y,(int) scrollRect.size.width,(int) scrollRect.size.height);
// printf ("bound rect: %d %d %d %d\n", (int) b.origin.x,(int) b.origin.y,(int) b.size.width,(int) b.size.height);
- (void)createFBO
if (!m_FBOId)
if (!isFBO)
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, m_FBOTexSize.width, m_FBOTexSize.height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_FBOTexId, 0);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, m_FBOTexSize.width, m_FBOTexSize.height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_FBODepthStencilPackedId);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_FBODepthStencilPackedId);
if (dockScreen)
if (!m_FBOThumbId)
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, m_FBOTexSize.width * m_FBOThumbScaleX, m_FBOTexSize.height * m_FBOThumbScaleY, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_FBOThumbTexId, 0);
- (void)deleteFBO
- (void)updateFBO
if (m_pGLCtx)
- (void)makeCurrentFBO
if (m_pGLCtx)
glFlush();
- (void)swapFBO
glFlush();
- (void)flushFBO
glFlush();
- (void)finishFBO
glFinish();
- (void)bindFBO
- (void)renderFBOToView
if (!m_pSharedGLCtx)
m_pSharedGLCtx = [[NSOpenGLContext alloc] initWithFormat:[(OverlayOpenGLContext*)m_pGLCtx openGLPixelFormat] shareContext:m_pGLCtx];
if (m_pSharedGLCtx)
glFlush();
GLint i;
glEnd();
glFinish();
[[[NSApplication sharedApplication] dockTile] performSelectorOnMainThread:@selector(display) withObject:nil waitUntilDone:NO];
GLint i;
glEnd();
glFinish();
- (void)clearVisibleRegions
if(m_paClipRects)
screenContent = [contentView performSelector:@selector(screenContentWithParentView:) withObject:(id)m_pParentView];
return screenContent;
- (void)reshapeDockTile
NSRect newFrame = NSMakeRect ((int)(m_Pos.x * m_FBOThumbScaleX), (int)(dockFrame.size.height - (m_Pos.y + m_Size.height - m_RootShift.y) * m_FBOThumbScaleY), (int)(m_Size.width * m_FBOThumbScaleX), (int)(m_Size.height * m_FBOThumbScaleY));
// NSRect newFrame = NSMakeRect ((int)roundf(m_Pos.x * m_FBOThumbScaleX), (int)roundf(dockFrame.size.height - (m_Pos.y + m_Size.height) * m_FBOThumbScaleY), (int)roundf(m_Size.width * m_FBOThumbScaleX), (int)roundf(m_Size.height * m_FBOThumbScaleY));
// NSRect newFrame = NSMakeRect ((m_Pos.x * m_FBOThumbScaleX), (dockFrame.size.height - (m_Pos.y + m_Size.height) * m_FBOThumbScaleY), (m_Size.width * m_FBOThumbScaleX), (m_Size.height * m_FBOThumbScaleY));
// printf ("%f %f %f %f - %f %f\n", newFrame.origin.x, newFrame.origin.y, newFrame.size.width, newFrame.size.height, m_Size.height, m_FBOThumbScaleY);
@end
if (pFmt)
OverlayView* pView = [[OverlayView alloc] initWithFrame:NSZeroRect thread:RTThreadSelf() parentView:pParentView];
if (pView)
if (pOView)
void cocoaFlush()
if (pCtx)
if (pView)
glFlush();
void cocoaFinish()
if (pCtx)
if (pView)
glFinish();
if (pCtx)
if (pView)