renderspu_cocoa_helper.m revision c02f671450508a0b9f4475f5d851cc078c8c01b8
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * VirtualBox OpenGL Cocoa Window System Helper Implementation.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * This source file is shared between the SharedOpenGL HGCM service and the
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * SVGA3d emulation.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Copyright (C) 2009-2014 Oracle Corporation
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * This file is part of VirtualBox Open Source Edition (OSE), as
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * available from http://www.virtualbox.org. This file is free software;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * you can redistribute it and/or modify it under the terms of the GNU
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * General Public License (GPL) as published by the Free Software
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Foundation, in version 2 as it comes in the "COPYING" file of the
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/** @page pg_opengl_cocoa OpenGL - Cocoa Window System Helper
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * How this works:
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * In general it is not so easy like on the other platforms, cause Cocoa
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * doesn't support any clipping of already painted stuff. In Mac OS X there is
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * the concept of translucent canvas's e.g. windows and there it is just
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * painted what should be visible to the user. Unfortunately this isn't the
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * concept of chromium. Therefor I reroute all OpenGL operation from the guest
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * to a frame buffer object (FBO). This is a OpenGL extension, which is
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * supported by all OS X versions we support (AFAIC tell). Of course the guest
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * doesn't know that and we have to make sure that the OpenGL state always is
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * in the right state to paint into the FBO and not to the front/back buffer.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Several functions below (like cocoaBindFramebufferEXT, cocoaGetIntegerv,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * ...) doing this. When a swap or finish is triggered by the guest, the
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * content (which is already bound to an texture) is painted on the screen
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * within a separate OpenGL context. This allows the usage of the same
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * resources (texture ids, buffers ...) but at the same time having an
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * different internal OpenGL state. Another advantage is that we can paint a
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * thumbnail of the current output in a much more smaller (GPU accelerated
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * scale) version on a third context and use glReadPixels to get the actual
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * data. glReadPixels is a very slow operation, but as we just use a much more
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * smaller image, we can handle it (anyway this is only done 5 times per
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Other things to know:
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * - If the guest request double buffering, we have to make sure there are two
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * buffers. We use the same FBO with 2 color attachments. Also glDrawBuffer
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * and glReadBuffer is intercepted to make sure it is painted/read to/from
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * the correct buffers. On swap our buffers are swapped and not the
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * - If the guest request a depth/stencil buffer, a combined render buffer for
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * this is created.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * - If the size of the guest OpenGL window changes, all FBO's, textures, ...
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * need to be recreated.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * - We need to track any changes to the parent window
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * (create/destroy/move/resize). The various classes like OverlayHelperView,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * OverlayWindow, ... are there for.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * - The HGCM service runs on a other thread than the Main GUI. Keeps this
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * always in mind (see e.g. performSelectorOnMainThread in renderFBOToView)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * - We make heavy use of late binding. We can not be sure that the GUI (or any
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * other third party GUI), overwrite our NSOpenGLContext. So we always ask if
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * this is our own one, before use. Really neat concept of Objective-C/Cocoa
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/*******************************************************************************
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome* Header Files *
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome*******************************************************************************/
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome#undef PVM /* sys/param.h (included via Cocoa.h) pollutes the namespace with this define. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# include "chromium.h" /* For the visual bits of chromium */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/*******************************************************************************
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome* Defined Constants And Macros *
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome*******************************************************************************/
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/* Debug macros */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Disable this to see how the output is without the FBO in the middle of the processing chain. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/** @def CR_RENDER_FORCE_PRESENT_MAIN_THREAD
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Force present schedule to main thread. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/** @def SHOW_WINDOW_BACKGROUND
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Define this to see the window background even if the window is clipped. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/** @def DEBUG_VERBOSE
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Define this to get some debug info about the messages flow. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_INFO(text) do { LogRel(text); AssertFailed(); } while (0)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_WARN(text) do { LogRel(text); AssertFailed(); } while (0)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_INFO(text) do { LogRel(text); AssertFailed(); } while (0)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_WARN(text) do { LogRel(text); AssertFailed(); } while (0)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_MSG(text) do { LogRel(text); } while (0)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_MSG_1(text) do { LogRel(text); } while (0)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_INFO(text) do { LogRel(text); } while (0)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_WARN(text) do { LogRel(text); } while (0)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_INFO(text) do { crInfo text; } while (0)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_WARN(text) do { crWarning text; } while (0)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_MSG_NOT_VMSVGA3D(a_TextArgs) do {} while (0)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define COCOA_LOG_FLOW(a_TextArgs) LogFlow(a_TextArgs)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_MSG_NOT_VMSVGA3D(a_TextArgs) DEBUG_MSG(a_TextArgs)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define COCOA_LOG_FLOW(a_TextArgs) DEBUG_MSG(a_TextArgs)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome#define DEBUG_FUNC_ENTER() DEBUG_MSG(("==>%s\n", __PRETTY_FUNCTION__))
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome#define DEBUG_FUNC_LEAVE() DEBUG_MSG(("<==%s\n", __PRETTY_FUNCTION__))
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); \
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome { /* nothing */ } \
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome AssertMsgFailed((a_szOp ": iGlCheckErr=%#x\n", iGlCheckErr)); \
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_CLEAR_GL_ERRORS() do {} while (0)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define DEBUG_CHECK_GL_ERROR(a_szOp) do {} while (0)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/* Whether we control NSView automatic content zooming on Retina/HiDPI displays. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * VMSVGA3D compatibility glue.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# define VMSVGA3D_NON_DEFAULT_PROFILE_BIT RT_BIT_32(31)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome return false;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSOpenGLContext *pCtx = [NSOpenGLContext currentContext];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome WindowInfo *pWinInfo = pCtxInfo->currentWindow;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome renderspu_SystemMakeCurrent(pWinInfo, 0, pCtxInfo);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * State carrying structure for use with vboxCtxEnter and vboxCtxLeave
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/** Pointer to render context info for use with vboxCtxEnter/Leave. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soometypedef VBOX_CR_RENDER_CTX_INFO *PVBOX_CR_RENDER_CTX_INFO;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomestatic void vboxCtxEnter(NSOpenGLContext *pNewCtx, PVBOX_CR_RENDER_CTX_INFO pCtxInfo)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSOpenGLContext *pOldCtx = vboxCtxGetCurrent();
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSView *pOldView = pOldCtx ? [pOldCtx view] : nil;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /** @todo r=bird: Why do we save the NEW VIEW here? vboxCtxLeave calls it 'pOldView'. Bug? */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* No context switch necessary. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomestatic void vboxCtxLeave(PVBOX_CR_RENDER_CTX_INFO pCtxInfo)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* vboxCtxEnter saves the new view, not the old. So, what we actually
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome do here is switching the view of the old context to that of the new
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome one (wrt vboxCtxEnter) before making it current. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /** @todo r=bird: Figure out what we really want to do here, and either rename
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * pOldView or fix the code. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSOpenGLContext *pTstOldCtx = [NSOpenGLContext currentContext];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSView *pTstOldView = pTstOldCtx ? [pTstOldCtx view] : nil;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Custom OpenGL context class.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * This implementation doesn't allow to set a view to the context, but save the
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * view for later use. Also it saves a copy of the pixel format used to create
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * that context for later use.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome@interface OverlayOpenGLContext: NSOpenGLContext
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Abstrack task class.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/** Run method that the child classes must reimplement.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * This will abort the process. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Generic task class for executing a given method select.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (id)initWithObject:(id)aObject selector:(SEL)aSelector arg:(id)aArg;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Initializes a VBoxTaskPerformSelector.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * @param aObject The object (reference not consumed).
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * @param aSelector The method selector.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * @param aArg The method argument (reference not consumed).
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (id)initWithObject:(id)aObject selector:(SEL)aSelector arg:(id)aArg
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [m_Object performSelector:m_Selector withObject:m_Arg];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("RTCritSectInit failed %d\n", rc));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Adds a task to the composite task object.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * @param pTask Task to add. Reference is NOT consumed.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("RTCritSectEnter failed %d\n", rc));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Dequeue a task.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("RTCritSectEnter failed %d\n", rc));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxTask *pTask = (VBoxTask *)[m_pArray objectAtIndex:m_CurIndex];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Remove the first 1025 empty entires.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Run the task and release it.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxTask *pTask = (VBoxTask*)[m_pArray objectAtIndex:m_CurIndex];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("dealloc with non-empty tasks! %p\n", pTask));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)addObj:(id)aObject selector:(SEL)aSelector arg:(id)aArg;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome static VBoxMainThreadTaskRunner *s_pRunner = nil;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome s_pRunner = [[VBoxMainThreadTaskRunner alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /** @todo r=bird: Unbalanced [self retain]. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [self performSelectorOnMainThread:@selector(runTasks) withObject:nil waitUntilDone:NO];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Adds a task calling an object method (selector).
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * @param aObject The object (reference not consumed)..
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * @param aSelector The method selector.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * @param aArg The method argument (reference not consumed).
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)addObj:(id)aObject selector:(SEL)aSelector arg:(id)aArg
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxTaskPerformSelector *pSelTask = [[VBoxTaskPerformSelector alloc] initWithObject:aObject selector:aSelector arg:aArg];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Internal method for running the pending tasks.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /** @todo r=bird: This release and the retain in the add method aren't
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * necessarily balanced if there are more than one call to add().
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * This could probably end up deleting the singleton prematurely and leave
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * globalInstance() returning pointers to a stale object in freed memory,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * quite possibly causing crashes or/and heap corruption. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("run tasks called not on main thread!\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [self performSelectorOnMainThread:@selector(runTasks) withObject:nil waitUntilDone:YES];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Callback for calling runTasks via renderspuCalloutClient.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * @param pvUser The VBoxMainThreadTaskRunner singleton.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomestatic DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxMainThreadTaskRunner *pRunner = (VBoxMainThreadTaskRunner *)pvUser;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome Assert(pRunner == [VBoxMainThreadTaskRunner globalInstance]);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Runs pending tasks synchronously, if possible in the current context.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * @returns true if executed tasks, false if not possible.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Call on main thread (?) via renderspuCalloutClient (whatever that is).
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome renderspuCalloutClient(VBoxMainThreadTaskRunner_RcdRunCallback, self);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome return true;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Run directly if on main thread.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome return true;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Not possible. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome return false;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /** @todo r=bird: WTF is the point of the deallocator. The object is a singelton
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * stored in an inaccessible static variable! */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * The custom view class.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * This is the main class of the cocoa OpenGL implementation. It manages a
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * frame buffer object for the rendering of the guest applications. The guest
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * applications render in this frame buffer which is bound to an OpenGL texture.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * To display the guest content, a secondary shared OpenGL context of the main
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * OpenGL context is created. The secondary context is marked as non-opaque and
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * the texture is displayed on an object which is composed out of the several
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * visible region rectangles.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /** The corresponding dock tile view of this OpenGL view & all helper
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * members. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /** @name For clipping
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * @remarks appears to be unused and a complete waste of time + heap.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /** @name Position/Size tracking
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /** This is necessary for clipping on the root window */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (id)initWithFrame:(NSRect)frame thread:(RTTHREAD)aThread parentView:(NSView *)pParentView winInfo:(WindowInfo *)pWinInfo;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (NSRect)safeConvertRectToBacking:(NSRect *)pRect;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)vboxSetVisibleUIObj:(NSNumber *)pVisible;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)vboxPresent:(const VBOXVR_SCR_COMPOSITOR *)pCompositor;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)vboxPresentCS:(const VBOXVR_SCR_COMPOSITOR *)pCompositor;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)vboxPresentToDockTileCS:(const VBOXVR_SCR_COMPOSITOR *)pCompositor;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)vboxPresentToViewCS:(const VBOXVR_SCR_COMPOSITOR *)pCompositor;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)presentComposition:(const VBOXVR_SCR_COMPOSITOR_ENTRY *)pChangedEntry;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)setVisibleRegions:(GLint)cRects paRects:(const GLint *)paRects;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Helper view.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * This view is added as a sub view of the parent view to track
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * main window changes. Whenever the main window is changed
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * (which happens on fullscreen/seamless entry/exit) the overlay
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * window is informed & can add them self as a child window
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome-(id)initWithOverlayWindow:(OverlayWindow *)pOverlayWindow;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Custom window class.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * This is the overlay window which contains our custom NSView.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Its a direct child of the Qt Main window. It marks its background
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * transparent & non opaque to make clipping possible. It also disable mouse
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * events and handle frame change events of the parent view.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (id)initWithParentView:(NSView *)pParentView overlayView:(OverlayView *)pOverlayView;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)parentWindowFrameChanged:(NSNotification *)note;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)parentWindowChanged:(NSWindow *)pWindow;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Dock overlay view class.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * We need a lock cause the thumb image could be accessed from the main
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * thread when someone is calling display on the dock tile & from the
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * OpenGL thread when the thumbnail is updated.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Create a buffer for our thumbnail image. Its in the size of this view. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome m_ThumbBitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome m_ThumbImage = [[NSImage alloc] initWithSize:[m_ThumbBitmap size]];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [m_ThumbImage addRepresentation:m_ThumbBitmap];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:0.7] set];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [NSBezierPath fillRect:NSMakeRect(0, 0, frame.size.width, frame.size.height)];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [m_ThumbImage drawAtPoint:NSMakePoint(0, 0) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/********************************************************************************
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome* OverlayOpenGLContext class implementation
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome********************************************************************************/
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome-(id)initWithFormat:(NSOpenGLPixelFormat *)format shareContext:(NSOpenGLContext *)share
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome self = [super initWithFormat:format shareContext:share];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("OCTX(%p): init OverlayOpenGLContext\n", (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("OCTX(%p): dealloc OverlayOpenGLContext\n", (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [m_pPixelFormat getValues:&val forAttribute:NSOpenGLPFADoubleBuffer forVirtualScreen:0];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("OCTX(%p): setView: new view: %p\n", (void *)self, (void *)view));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome return [super view];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("OCTX(%p): clearDrawable\n", (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/********************************************************************************
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome* OverlayHelperView class implementation
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome********************************************************************************/
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome-(id)initWithOverlayWindow:(OverlayWindow *)pOverlayWindow
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("OHVW(%p): init OverlayHelperView\n", (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("OHVW(%p): viewDidMoveToWindow: new win: %p\n", (void *)self, (void *)[self window]));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [m_pOverlayWindow parentWindowChanged:[self window]];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/********************************************************************************
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome* OverlayWindow class implementation
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome********************************************************************************/
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (id)initWithParentView:(NSView *)pParentView overlayView:(OverlayView *)pOverlayView
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome self = [super initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome m_pOverlayHelperView = [[OverlayHelperView alloc] initWithOverlayWindow:self];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Add the helper view as a child of the parent view to get notifications */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Make sure this window is transparent */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* For debugging */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [self setBackgroundColor:[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:0.7]];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [self setBackgroundColor:[NSColor clearColor]];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Disable mouse events for this window */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Initial set the position to the parents view top/left (Compiz fix). */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [m_pParentView convertPoint:NSZeroPoint toView:nil]]];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Set the overlay view as our content view */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Add ourself as a child to the parent views window. Note: this has to
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * be done last so that everything else is setup in
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * parentWindowChanged. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [pParentWin addChildWindow:self ordered:NSWindowAbove];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("OWIN(%p): init OverlayWindow\n", (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("OWIN(%p): dealloc OverlayWindow\n", (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [[NSNotificationCenter defaultCenter] removeObserver:self];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)parentWindowFrameChanged:(NSNotification *)pNote
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("OWIN(%p): parentWindowFrameChanged\n", (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Reposition this window with the help of the OverlayView. Perform the
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * call in the OpenGL thread.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [m_pOverlayView performSelector:@selector(vboxReshapePerform) onThread:m_Thread withObject:nil waitUntilDone:YES];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [self performSelectorOnMainThread:@selector(vboxReshapePerform) withObject:nil waitUntilDone:NO];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("OWIN(%p): parentWindowChanged\n", (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [[NSNotificationCenter defaultCenter] removeObserver:self];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Ask to get notifications when our parent window frame changes. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Add us self as child window */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [pWindow addChildWindow:self ordered:NSWindowAbove];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Reshape the overlay view after a short waiting time to let the main
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * window resize itself properly.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [m_pOverlayView performSelector:@selector(vboxReshapePerform) withObject:nil afterDelay:0.2];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [NSTimer scheduledTimerWithTimeInterval:0.2 target:m_pOverlayView selector:@selector(vboxReshapePerform) userInfo:nil repeats:NO];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [self performSelectorOnMainThread:@selector(vboxReshapePerform) withObject:nil waitUntilDone:NO];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/********************************************************************************
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome* OverlayView class implementation
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome********************************************************************************/
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (id)initWithFrame:(NSRect)frame thread:(RTTHREAD)aThread parentView:(NSView *)pParentView winInfo:(WindowInfo *)pWinInfo
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p aThread=%p pParentView=%p pWinInfo=%p\n", __PRETTY_FUNCTION__, (void *)self,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (void *)aThread, (void *)pParentView, (void *)pWinInfo));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Make some reasonable defaults */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome m_RootRect = NSMakeRect(0, 0, m_Size.width, m_Size.height);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome#if defined(VBOX_WITH_CONFIGURABLE_HIDPI_SCALING) && !defined(IN_VMSVGA3D)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Always allocate HiDPI-ready backing store for NSView, so we will be able change HiDPI scaling option in runtime. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome crDebug("HiDPI: Allocate big backing store for NSView. Up-scaling is currently %s.", render_spu.fUnscaledHiDPI ? "OFF" : "ON");
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [self performSelector:@selector(setWantsBestResolutionOpenGLSurface:) withObject: (id)YES];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns self=%p\n", __PRETTY_FUNCTION__, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p aRect=%d,%d %d,%d\n", __PRETTY_FUNCTION__, (void *)self, (int)aRect.origin.x, (int)aRect.origin.y,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)aRect.size.width, (int)aRect.size.height));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pCtx=%p (old=%p)\n", __PRETTY_FUNCTION__, (void *)self, (void *)pCtx, m_pGLCtx));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Only do something if the context changes.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Ensure the context drawable is cleared to avoid holding a reference to inexistent view. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /*[m_pGLCtx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];*/
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p returns %p\n", __PRETTY_FUNCTION__, (void *)self, (void *)m_pGLCtx));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p returns %p\n", __PRETTY_FUNCTION__, (void *)self, (void *)m_pParentView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pView=%p (old=%p)\n", __PRETTY_FUNCTION__, (void *)self, (void *)pView, m_pParentView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pWin=%p (old=%p)\n", __PRETTY_FUNCTION__, (void *)self, (void *)pWin, m_pOverlayWin));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p returns %p\n", __PRETTY_FUNCTION__, (void *)self, (void *)m_pOverlayWin));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pos=%d,%d (old pos=%d,%d)\n", __PRETTY_FUNCTION__, (void *)self, (int)pos.x, (int)pos.y,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("vboxSetPosUI: [%d, %d].\n", (int)pos.x, (int)pos.y));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pPos=%p (%d,%d) (old pos=%d,%d)\n", __PRETTY_FUNCTION__, (void *)self, pPos,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)[pPos pointValue].x, (int)[pPos pointValue].y, (int)m_Pos.x, (int)m_Pos.y));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pos=%d,%d (old pos=%d,%d)\n", __PRETTY_FUNCTION__, (void *)self, (int)pos.x, (int)pos.y,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [pRunner addObj:self selector:@selector(vboxSetPosUIObj:) arg:pPos];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p returns %d,%d\n", __PRETTY_FUNCTION__, (void *)self, (int)m_Pos.x, (int)m_Pos.y));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p returns %d\n", __PRETTY_FUNCTION__, (void *)self, m_fEverSized));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Hide the view early. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [[NSNotificationCenter defaultCenter] removeObserver:pWin];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* We can NOT run synchronously with the main thread since this may lead to a deadlock,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome caused by main thread waiting xpcom thread, xpcom thread waiting to main hgcm thread,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome and main hgcm thread waiting for us, this is why use waitUntilDone:NO,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome which should cause no harm. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [pWin performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* We can NOT run synchronously with the main thread since this may lead to a deadlock,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome caused by main thread waiting xpcom thread, xpcom thread waiting to main hgcm thread,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome and main hgcm thread waiting for us, this is why use waitUntilDone:NO.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome We need to avoid concurrency though, so we cleanup some data right away via a cleanupData call. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [self performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pSize=%p (%d,%d)\n", __PRETTY_FUNCTION__, (void *)self, (void *)pSize,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)[pSize sizeValue].width, (int)[pSize sizeValue].height));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p size=%d,%d\n", __PRETTY_FUNCTION__, (void *)self, (int)size.width, (int)size.height));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("OVIW(%p): vboxSetSize: new size: %dx%d\n", (void *)self, (int)m_Size.width, (int)m_Size.height));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* ensure window contents is updated after that */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p size=%d,%d\n", __PRETTY_FUNCTION__, (void *)self, (int)size.width, (int)size.height));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [pRunner addObj:self selector:@selector(vboxSetSizeUIObj:) arg:pSize];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p returns %d,%d\n", __PRETTY_FUNCTION__, (void *)self, (int)m_Size.width, (int)m_Size.height));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Update the viewport for our OpenGL view. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Clear background to transparent. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* have to rebind GL_TEXTURE_RECTANGLE_ARB as m_FBOTexId could be changed in updateFBO call */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome if (pCurCtx && pCurCtx == m_pGLCtx && (pCurView = [pCurCtx view]) == self)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* do it in a lazy way */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (NSRect)safeConvertRectToBacking:(NSRect *)pRect
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome if ([pWindow respondsToSelector:@selector(convertRectToBacking:)])
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSMethodSignature *pSignature = [pWindow methodSignatureForSelector:@selector(convertRectToBacking:)];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSInvocation *pInvocation = [NSInvocation invocationWithMethodSignature:pSignature];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [pInvocation setSelector:@selector(convertRectToBacking:)];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("safeConvertRectToBacking: convert [X, Y, WxH]: [%d, %d, %dx%d] -> [%d, %d, %dx%d]\n",
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)pRect ->origin.x, (int)pRect ->origin.y, (int)pRect ->size.width, (int)pRect ->size.width,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)resultingRect.origin.x, (int)resultingRect.origin.y, (int)resultingRect.size.width, (int)resultingRect.size.width));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Should never happen. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("safeConvertRectToBacking: parent widget has no window.\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("safeConvertRectToBacking (reurn as is): convert [X, Y, WxH]: [%d, %d, %dx%d] -> [%d, %d, %dx%d]\n",
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)pRect ->origin.x, (int)pRect ->origin.y, (int)pRect ->size.width, (int)pRect ->size.width,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)resultingRect.origin.x, (int)resultingRect.origin.y, (int)resultingRect.size.width, (int)resultingRect.size.width));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Assume its default value. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome if ([pScreen respondsToSelector:@selector(backingScaleFactor)])
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSMethodSignature *pSignature = [pScreen methodSignatureForSelector:@selector(backingScaleFactor)];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSInvocation *pInvocation = [NSInvocation invocationWithMethodSignature:pSignature];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [pInvocation setSelector:@selector(backingScaleFactor)];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [pInvocation getReturnValue:&backingScaleFactor];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("safeGetBackingScaleFactor: %d\n", (int)backingScaleFactor));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("safeGetBackingScaleFactor: unable to create invocation for backingScaleFactor method signature.\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("safeGetBackingScaleFactor: unable to create method signature for backingScaleFactor selector.\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("safeGetBackingScaleFactor: NSScreen does not respond to backingScaleFactor selector.\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Should never happen. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("safeGetBackingScaleFactor: parent window has no screen.\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Should never happen. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("safeGetBackingScaleFactor: parent widget has no window.\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome if ([pWindow respondsToSelector:@selector(convertRectToScreen:)])
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSMethodSignature *pSignature = [pWindow methodSignatureForSelector:@selector(convertRectToScreen:)];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSInvocation *pInvocation = [NSInvocation invocationWithMethodSignature:pSignature];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [pInvocation setSelector:@selector(convertRectToScreen:)];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("safeConvertToScreen: convert [X, Y, WxH]: [%d, %d, %dx%d] -> [%d, %d, %dx%d]\n",
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)pRect ->origin.x, (int)pRect ->origin.y, (int)pRect ->size.width, (int)pRect ->size.width,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)resultingRect.origin.x, (int)resultingRect.origin.y, (int)resultingRect.size.width, (int)resultingRect.size.width));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* If we failed, let's use deprecated @selector(convertBaseToScreen:). It is a bit hacky,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * but what to do if we stick to SDK 10.6. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome resultingRect.origin = [[m_pParentView window] convertBaseToScreen:pRect->origin];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Should never happen. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("safeConvertToScreen: parent widget has no window.\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("safeConvertToScreen (deprecated method): convert [X, Y, WxH]: [%d, %d, %dx%d] -> [%d, %d, %dx%d]\n",
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)pRect ->origin.x, (int)pRect ->origin.y, (int)pRect ->size.width, (int)pRect ->size.width,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)resultingRect.origin.x, (int)resultingRect.origin.y, (int)resultingRect.size.width, (int)resultingRect.size.width));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p - m_DockTileView=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)m_DockTileView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* NOTE: Please consider the next naming convention for variables.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Rectangle variables:
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * <object to represent><coordinate system>:
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * <object to represent>:
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * parentFrame - a frame of the parent container (NSView) object
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * childFrame - a frame required to display guest content
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * windowFrame - resulting window frame constructed as an intersection of parentFrame and childFrame
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * <coordinate system>:
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * VCS - View Coordinate System
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * WCS - Window Coordinate System
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * SCS - Screen Coordinate System
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * The same convention applied to offset variables naming as well which are of format:
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * <object to represent><coordinate><coordinate system>.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Transforms/Transforms.html
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSRect parentFrameVCS, parentFrameWCS, parentFrameSCS;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* We need to construct a new window frame (windowFrameSCS) for entire NSWindow object in
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * screen coordinates. In order to make 3D overlay window to do not overlap Cocoa and Qt GUI elements (titlebar,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Qt statusbar, scroll bars etc) let's do the next. Get parent view visible area (parentFrameSCS) in (NS)Screen
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * coordinates. Then get the area required to diaplay guest content (childFrameSCS) in (NS)Screen coordinates as well.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * The intersection of these two areas in screen coordinates will be a new frame for entire NSWindow object. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome parentFrameWCS = [m_pParentView convertRect:parentFrameVCS toView:nil];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome parentFrameSCS = [self safeConvertToScreen:&parentFrameWCS];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Choose childFrame origin in a bit special way. Its pop-left corner should stick to its parent top-left corner. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome childFrameXWCS = parentFrameWCS.origin.x + m_Pos.x;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome childFrameYWCS = parentFrameWCS.origin.y - m_Pos.y - (m_Size.height - parentFrameWCS.size.height);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome childFrameWCS = NSMakeRect(childFrameXWCS, childFrameYWCS, m_Size.width, m_Size.height);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome childFrameSCS = [self safeConvertToScreen:&childFrameWCS];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome windowFrameSCS = NSIntersectionRect(parentFrameSCS, childFrameSCS);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("vboxReshapePerform: a new overlay frame [%d, %d, %dx%d] has been constructed from intersection of window frame "
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome "[%d, %d, %dx%d] and guest content rectangle [%d, %d, %dx%d]; m_Pos=[%d, %d], m_Size=%dx%d.\n",
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)windowFrameSCS.origin.x, (int)windowFrameSCS.origin.y, (int)windowFrameSCS.size.width, (int)windowFrameSCS.size.width,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)parentFrameSCS.origin.x, (int)parentFrameSCS.origin.y, (int)parentFrameSCS.size.width, (int)parentFrameSCS.size.width,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)childFrameSCS .origin.x, (int)childFrameSCS .origin.y, (int)childFrameSCS .size.width, (int)childFrameSCS .size.width,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)m_Pos.x, (int)m_Pos.y, (int)m_Size.width, (int)m_Size.height));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* @todo galitsyn: drop this!
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Later we have to correct the texture position in the case the window is
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * out of the parents window frame. So save the shift values for later use. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome m_RootRect.origin.x = windowFrameSCS.origin.x - childFrameSCS.origin.x;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome m_RootRect.origin.y = childFrameSCS.size.height + childFrameSCS.origin.y - (windowFrameSCS.size.height + windowFrameSCS.origin.y);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome m_yInvRootOffset = windowFrameSCS.origin.y - childFrameSCS.origin.y;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("vboxReshapePerform: [%#p]: m_RootRect pos[%d : %d] size[%d : %d]\n",
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (void *)self, (int)m_RootRect.origin.x, (int)m_RootRect.origin.y, (int)m_RootRect.size.width, (int)m_RootRect.size.height));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Set the new frame. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [[self window] setFrame:windowFrameSCS display:YES];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Inform the dock tile view as well. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Make sure the context is updated accordingly. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* [self updateViewport]; */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Is there a dock tile preview enabled in the GUI? If so setup a
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * additional thumbnail view for the dock tile. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome m_DockTileView = [[DockOverlayView alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns - m_DockTileView\n", __PRETTY_FUNCTION__, (void *)m_DockTileView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p - m_DockTileView=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)m_DockTileView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p - m_pGLCtx=%p m_fNeedCtxUpdate=%d\n", __PRETTY_FUNCTION__, (void *)self,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSOpenGLContext *pPrevCtx = [NSOpenGLContext currentContext];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Always flush before flush. glXMakeCurrent and wglMakeCurrent does this
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome implicitly, seemingly NSOpenGLContext::makeCurrentContext doesn't. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* We change the active view, so flush first */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome Assert([NSOpenGLContext currentContext] == m_pGLCtx);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns true (m_pSharedGLCtx=%p)\n", __PRETTY_FUNCTION__, (void *)m_pSharedGLCtx));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome return true;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns false - m_pBlitter allocation failed\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome return false;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome int rc = CrBltInit(m_pBlitter, NULL, false /*fCreateNewCtx*/, false /*fForceDrawBlt*/,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome &render_spu.GlobalShaders, &render_spu.blitterDispatch);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns false - CrBltInit failed with rc=%Rrc\n", __PRETTY_FUNCTION__, rc));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome return false;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: blitter (%p) created successfully for view 0x%p\n", (void *)m_pBlitter, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Create a shared context out of the main context. Use the same pixel format. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSOpenGLPixelFormat *pPixelFormat = [(OverlayOpenGLContext *)m_pGLCtx openGLPixelFormat];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSOpenGLContext *pSharedGLCtx = [[NSOpenGLContext alloc] initWithFormat:pPixelFormat shareContext:m_pGLCtx];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Set the new context as non opaque */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [pSharedGLCtx setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Set this view as the drawable for the new context */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns true - new m_pSharedGLCtx=%p\n", __PRETTY_FUNCTION__, (void *)m_pSharedGLCtx));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome return true;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Issue to the gui thread. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [self performSelectorOnMainThread:@selector(vboxTryDrawUI) withObject:nil waitUntilDone:NO];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p fVisible=%d\n", __PRETTY_FUNCTION__, (void *)self, fVisible));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSNumber *pVisObj = [NSNumber numberWithBool:fVisible];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [pRunner addObj:self selector:@selector(vboxSetVisibleUIObj:) arg:pVisObj];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p fVisible=%d\n", __PRETTY_FUNCTION__, (void *)self, fVisible));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)vboxSetVisibleUIObj:(NSNumber *)pVisibleObj
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pVisibleObj=%p(%d)\n", __PRETTY_FUNCTION__,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (void *)self, (void *)pVisibleObj, [pVisibleObj boolValue]));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pParentView=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pParentView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [pRunner addObj:self selector:@selector(vboxReparentUI:) arg:pParentView];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pParentView=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pParentView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Make sure the window is removed from any previous parent window. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [[[self overlayWin] parentWindow] removeChildWindow:[self overlayWin]];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Set the new parent view */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Add the overlay window as a child to the new parent window */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [[pParentView window] addChildWindow:[self overlayWin] ordered:NSWindowAbove];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns - request to draw on a hidden view\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns - request to draw a view w/o a parent\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns - vboxSharedCtxCreate failed\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome const VBOXVR_SCR_COMPOSITOR *pCompositor = NULL;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome int rc = renderspuVBoxCompositorLock(m_pWinInfo, &pCompositor);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns - renderspuVBoxCompositorLock failed (%Rrc)\n", __PRETTY_FUNCTION__, rc));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns - noCompositorUI\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns - vboxSharedCtxCreate failed\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pCompositor = renderspuVBoxCompositorAcquire(m_pWinInfo);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns - Failed to reacquire compositor\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG(("%s: NeedCleanup\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: Calling vboxPresent\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: NotVisible\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: Reschedule\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(vboxTryDrawUI) userInfo:nil repeats:NO];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p - m_pGLCtx=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)m_pGLCtx));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)vboxPresent:(PCVBOXVR_SCR_COMPOSITOR)pCompositor
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pCompositor=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pCompositor));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /*DEBUG_MSG(("OVIW(%p): renderFBOToView\n", (void *)self));*/
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)vboxPresentCS:(PCVBOXVR_SCR_COMPOSITOR)pCompositor
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pCompositor=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pCompositor));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: Not current view of shared ctx! Switching... (self=%p, view=%p, m_pSharedGLCtx)\n",
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome __PRETTY_FUNCTION__, (void *)self, (void *)[m_pSharedGLCtx view], (void *)m_pSharedGLCtx));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Render FBO content to the dock tile when necessary. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* change to #if 0 to see thumbnail image */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas SoomeDECLINLINE(void) vboxNSRectToRect(const NSRect *pR, RTRECT *pRect)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pRect->xRight = (int)(pR->origin.x + pR->size.width);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pRect->yBottom = (int)(pR->origin.y + pR->size.height);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas SoomeDECLINLINE(void) vboxNSRectToRectUnstretched(const NSRect *pR, RTRECT *pRect, float xStretch, float yStretch)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pRect->xRight = (int)((pR->origin.x + pR->size.width) / xStretch);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pRect->yBottom = (int)((pR->origin.y + pR->size.height) / yStretch);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas SoomeDECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, float xStretch, float yStretch)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pRect->xRight = (int)((pR->origin.x + pR->size.width) * xStretch);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pRect->yBottom = (int)((pR->origin.y + pR->size.height) * yStretch);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)vboxPresentToViewCS:(PCVBOXVR_SCR_COMPOSITOR)pCompositor
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p - r={%d,%d %d,%d}\n", __PRETTY_FUNCTION__, (void *)self,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)r.origin.x, (int)r.origin.y, (int)r.size.width, (int)r.size.height));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome#if 1 /* Set to 0 to see the docktile instead of the real output */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome# if defined(VBOX_WITH_CONFIGURABLE_HIDPI_SCALING) && !defined(IN_VMSVGA3D)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Adjust viewport according to current NSView's backing store parameters. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Update stretch factor in order to satisfy current NSView's backing store parameters. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome backingStretchFactor = [self safeGetBackingScaleFactor];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSRect backingBounds = [self safeConvertRectToBacking:®ularBounds];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome glViewport(0, 0, backingBounds.size.width, backingBounds.size.height);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome crDebug("HiDPI: vboxPresentToViewCS: up-scaling is %s (backingStretchFactor=%d).",
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome render_spu.fUnscaledHiDPI ? "OFF" : "ON", (int)backingStretchFactor);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Clear background to transparent */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome CrVrScrCompositorGetStretching(pCompositor, &xStretch, &yStretch);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome CrVrScrCompositorConstIterInit(pCompositor, &CIter);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRegions, &paSrcRegions, &paDstRegions, NULL);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome uint32_t fFlags = CrVrScrCompositorEntryFlagsCombinedGet(pCompositor, pEntry);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome vboxNSRectToRect(&m_RootRect, &RestrictDstRect);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxRectIntersected(&RestrictDstRect, pDstRect, &DstRect);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxRectTranslate(&DstRect, -RestrictDstRect.xLeft, -RestrictDstRect.yTop);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome vboxNSRectToRectUnstretched(&m_RootRect, &RestrictSrcRect, xStretch / backingStretchFactor, yStretch / backingStretchFactor);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxRectIntersected(&RestrictSrcRect, pSrcRect, &SrcRect);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pTexData = CrVrScrCompositorEntryTexGet(pEntry);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome CrBltBlitTexMural(m_pBlitter, true, CrTdTexGet(pTexData), pSrcRect, pDstRect, 1, fFlags | CRBLT_F_NOALPHA);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome AssertMsgFailed(("CrBltEnter failed rc %Rrc", rc));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome AssertMsgFailed(("BlitStretched: CrVrScrCompositorEntryRegionsGet failed rc %Rrc\n", rc));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG_1(("BlitStretched: CrVrScrCompositorEntryRegionsGet failed rc %d\n", rc));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)presentComposition:(PCVBOXVR_SCR_COMPOSITOR_ENTRY)pChangedEntry
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pChangedEntry=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pChangedEntry));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome Assert(WinInfo.width == m_RootRect.size.width);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome Assert(WinInfo.height == m_RootRect.size.height);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /*CrBltMuralSetCurrentInfo(m_pBlitter, NULL);*/
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome CrBltMuralSetCurrentInfo(m_pBlitter, &WinInfo);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)vboxPresentToDockTileCS:(PCVBOXVR_SCR_COMPOSITOR)pCompositor
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p pCompositor=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pCompositor));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * Only update after at least 200 ms, cause glReadPixels is
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * heavy performance wise.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* todo: check this for optimization */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome glBindTexture(GL_TEXTURE_RECTANGLE_ARB, myTextureName);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Do other work processing here, using a double or triple buffer */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome glGetTexImage(GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGRA,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Clear background to transparent */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome CrVrScrCompositorGetStretching(pCompositor, &xStretch, &yStretch);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome CrVrScrCompositorConstIterInit(pCompositor, &CIter);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRegions, &paSrcRegions, &paDstRegions, NULL);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome uint32_t fFlags = CrVrScrCompositorEntryFlagsCombinedGet(pCompositor, pEntry);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome vboxNSRectToRect(&m_RootRect, &RestrictDstRect);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxRectIntersected(&RestrictDstRect, pDstRect, &DstRect);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxRectTranslate(&DstRect, -RestrictDstRect.xLeft, -RestrictDstRect.yTop);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxRectScale(&DstRect, m_FBOThumbScaleX, m_FBOThumbScaleY);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome vboxNSRectToRectUnstretched(&m_RootRect, &RestrictSrcRect, xStretch, yStretch);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxRectIntersected(&RestrictSrcRect, pSrcRect, &SrcRect);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pTexData = CrVrScrCompositorEntryTexGet(pEntry);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome CrBltBlitTexMural(m_pBlitter, true, CrTdTexGet(pTexData), pSrcRect, pDstRect, 1, fFlags);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome AssertMsgFailed(("CrBltEnter failed rc %Rrc", rc));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG_1(("BlitStretched: CrVrScrCompositorEntryRegionsGet failed rc %d\n", rc));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome AssertMsgFailed(("BlitStretched: CrVrScrCompositorEntryRegionsGet failed rc %Rrc\n", rc));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Here the magic of reading the FBO content in our own buffer
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * happens. We have to lock this access, in the case the dock
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * is updated currently. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome glReadPixels(0, m_RootRect.size.height - rr.size.height, rr.size.width, rr.size.height,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome crDumpNamedTGAF((GLint)rr.size.width, (GLint)rr.size.height,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [[m_DockTileView thumbBitmap] bitmapData], "/Users/leo/vboxdumps/dump%d.tga", g_cVBoxTgaCtr);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pDT = [[NSApplication sharedApplication] dockTile];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Send a display message to the dock tile in the main thread */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [[[NSApplication sharedApplication] dockTile] performSelectorOnMainThread:@selector(display) withObject:nil
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome- (void)setVisibleRegions:(GLint)cRects paRects:(const GLint *)paRects
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p cRects=%d paRects=%p\n", __PRETTY_FUNCTION__, (void *)self, cRects, (void *)paRects));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG_1(("OVIW(%p): setVisibleRegions: %d - %d %d %d %d\n", (void *)self, i, paRects[i * 4], paRects[i * 4 + 1], paRects[i * 4 + 2], paRects[i * 4 + 3]));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome m_paClipRects = (GLint *)RTMemDup(paRects, sizeof(GLint) * 4 * cRects);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSView *pContentView = [[[NSApplication sharedApplication] dockTile] contentView];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * First try the new variant which checks if this window is within the
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * screen which is previewed in the dock.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome if ([pContentView respondsToSelector:@selector(screenContentWithParentView:)])
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pScreenContent = [pContentView performSelector:@selector(screenContentWithParentView:) withObject:(id)m_pParentView];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * If it fails, fall back to the old variant (VBox...).
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome else if ([pContentView respondsToSelector:@selector(screenContent)])
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pScreenContent = [pContentView performSelector:@selector(screenContent)];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns %p (pContentView=%p)\n", __PRETTY_FUNCTION__, (void *)pScreenContent, (void *)pContentView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s:\n", __PRETTY_FUNCTION__));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /** @todo This is not correct, we should use framebuffer size here, while
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * parent view frame size may differ in case of scrolling. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome m_FBOThumbScaleX = (float)dockFrame.size.width / parentFrame.size.width;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome m_FBOThumbScaleY = (float)dockFrame.size.height / parentFrame.size.height;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome newFrame = NSMakeRect((int)(m_Pos.x * m_FBOThumbScaleX),
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)(dockFrame.size.height - (m_Pos.y + m_Size.height - m_yInvRootOffset) * m_FBOThumbScaleY),
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome 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));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome 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));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome 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);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("%s: returns - newFrame={%d,%d %d,%d} pView=%d\n", __PRETTY_FUNCTION__, (int)newFrame.origin.x,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (int)newFrame.origin.y, (int)newFrame.size.width, (int)newFrame.size.height, (void *)pView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/********************************************************************************
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome* OpenGL context management
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome********************************************************************************/
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomevoid cocoaGLCtxCreate(NativeNSOpenGLContextRef *ppCtx, GLbitfield fVisParams, NativeNSOpenGLContextRef pSharedCtx)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaGLCtxCreate: ppCtx=%p fVisParams=%#x pSharedCtx=%p\n", (void *)ppCtx, fVisParams, (void *)pSharedCtx));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSOpenGLPFAOpenGLProfile, (NSOpenGLPixelFormatAttribute)0,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)24
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome if (fVisParams & VMSVGA3D_NON_DEFAULT_PROFILE_BIT)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome attribs[1] = VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE >= 3.2 ? NSOpenGLProfileVersionLegacy : NSOpenGLProfileVersion3_2Core;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome attribs[1] = VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE >= 3.2 ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW((" CR_STENCIL_BIT requested\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW((" CR_MULTISAMPLE_BIT requested\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW((" CR_DOUBLE_BIT requested\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* We don't support that.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW((" CR_STEREO_BIT requested\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome attribs[i++] = NSOpenGLPFAStereo;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW((" Offline rendering is enabled\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome attribs[i++] = NSOpenGLPFAAllowOfflineRenderers;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Mark the end */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Choose a pixel format */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome *ppCtx = [[OverlayOpenGLContext alloc] initWithFormat:pFmt shareContext:pSharedCtx];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Enable multi threaded OpenGL engine */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome CGLContextObj cglCtx = [*ppCtx CGLContextObj];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome CGLError err = CGLEnable(cglCtx, kCGLCEMPEngine);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome if (err != kCGLNoError)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome printf ("Couldn't enable MT OpenGL engine!\n");
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaGLCtxCreate: returns *ppCtx=%p\n", (void *)*ppCtx));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomevoid cocoaGLCtxDestroy(NativeNSOpenGLContextRef pCtx)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaGLCtxDestroy: pCtx=%p\n", (void *)pCtx));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /*[pCtx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];*/
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaGLCtxDestroy: returns\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome/********************************************************************************
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome* View management
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome********************************************************************************/
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomestatic OverlayView *vboxViewCreate(WindowInfo *pWinInfo, NativeNSViewRef pParentView)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("vboxViewCreate: pWinInfo=%p pParentView=%p\n", pWinInfo, (void *)pParentView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Create our worker view. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome OverlayView *pView = [[OverlayView alloc] initWithFrame:NSZeroRect
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* We need a real window as container for the view */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [[OverlayWindow alloc] initWithParentView:pParentView overlayView:pView];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Return the freshly created overlay view */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("vboxViewCreate: returns %p\n", (void *)pView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("vboxViewCreate: returns NULL\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomestatic DECLCALLBACK(void) vboxRcdCreateView(void *pvCb)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome CR_RCD_CREATEVIEW *pCreateView = (CR_RCD_CREATEVIEW *)pvCb;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pCreateView->pView = vboxViewCreate(pCreateView->pWinInfo, pCreateView->pParentView);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("vboxRcdCreateView: returns pView=%p\n", (void *)pCreateView->pView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomevoid cocoaViewCreate(NativeNSViewRef *ppView, WindowInfo *pWinInfo, NativeNSViewRef pParentView, GLbitfield fVisParams)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewCreate: ppView=%p pWinInfo=%p pParentView=%p fVisParams=%#x\n",
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (void *)ppView, (void *)pWinInfo, (void *)pParentView, fVisParams));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* make sure all tasks are run, to preserve the order */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome renderspuCalloutClient(vboxRcdCreateView, &CreateView);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG_NOT_VMSVGA3D(("no callout available on createWindow\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome *ppView = vboxViewCreate(pWinInfo, pParentView);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewCreate: returns *ppView=%p\n", (void *)*ppView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomevoid cocoaViewReparent(NativeNSViewRef pView, NativeNSViewRef pParentView)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewReparent: pView=%p pParentView=%p\n", (void *)pView, (void *)pParentView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewReparent: returns\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewDestroy: pView=%p\n", (void *)pView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [pRunner addObj:pView selector:@selector(vboxDestroy) arg:nil];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewDestroy: returns\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomevoid cocoaViewShow(NativeNSViewRef pView, GLboolean fShowIt)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewShow: pView=%p fShowIt=%d\n", (void *)pView, fShowIt));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewDisplay: pView=%p\n", (void *)pView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("cocoaViewDisplay should never happen!\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG_1(("cocoaViewDisplay %p\n", (void *)pView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewDisplay: returns\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomevoid cocoaViewSetPosition(NativeNSViewRef pView, NativeNSViewRef pParentView, int x, int y)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewSetPosition: pView=%p pParentView=%p x=%d y=%d\n", (void *)pView, (void *)pParentView, x, y));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [(OverlayView *)pView vboxSetPos:NSMakePoint(x, y)];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewSetPosition: returns\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomevoid cocoaViewSetSize(NativeNSViewRef pView, int cx, int cy)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewSetSize: pView=%p cx=%d cy=%d\n", (void *)pView, cx, cy));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [(OverlayView *)pView vboxSetSize:NSMakeSize(cx, cy)];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewSetSize: returns\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomestatic DECLCALLBACK(void) vboxRcdGetGeomerty(void *pvUser)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome CR_RCD_GETGEOMETRY *pGetGeometry = (CR_RCD_GETGEOMETRY *)pvUser;
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pGetGeometry->rect = [[pGetGeometry->pView window] frame];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("vboxRcdGetGeomerty: (x,y)=(%d,%d) (cx,cy)=(%d,%d)\n", pGetGeometry->rect.origin.x, pGetGeometry->rect.origin.y,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome pGetGeometry->rect.size.width, pGetGeometry->rect.size.height));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomevoid cocoaViewGetGeometry(NativeNSViewRef pView, int *px, int *py, int *pcx, int *pcy)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewGetGeometry: pView=%p px=%p py=%p pcx=%p pcy=%p\n",
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome (void *)pView, (void *)px, (void *)py, (void *)pcx, (void *)pcy));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* make sure all tasks are run, to preserve the order */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome renderspuCalloutClient(vboxRcdGetGeomerty, &GetGeometry);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_MSG_NOT_VMSVGA3D(("no callout available on getGeometry\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewGetGeometry: returns *px=%d, *py=%d, *pcx=%d, *pcy=%d\n", *px, *py, *pcx, *pcy));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomevoid cocoaViewPresentComposition(NativeNSViewRef pView, PCVBOXVR_SCR_COMPOSITOR_ENTRY pChangedEntry)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewPresentComposition: pView=%p pChangedEntry=%p\n", (void *)pView, (void *)pChangedEntry));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* view should not necesserily have a context set */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome ContextInfo *pCtxInfo = renderspuDefaultSharedContextAcquire();
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome DEBUG_WARN(("renderspuDefaultSharedContextAcquire returned NULL"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [(OverlayView *)pView presentComposition:pChangedEntry];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewPresentComposition: returns\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomevoid cocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewMakeCurrentContext: pView=%p pCtx=%p\n", (void *)pView, (void *)pCtx));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome /* Always flush before flush. glXMakeCurrent and wglMakeCurrent does this
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome implicitly, seemingly NSOpenGLContext::makeCurrentContext doesn't. */
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewMakeCurrentContext: returns\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas SoomeGLboolean cocoaViewNeedsEmptyPresent(NativeNSViewRef pView)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewNeedsEmptyPresent: pView=%p\n", (void *)pView));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome GLboolean fNeedsPresent = [(OverlayView *)pView vboxNeedsEmptyPresent];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewNeedsEmptyPresent: returns %d\n", fNeedsPresent));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soomevoid cocoaViewSetVisibleRegion(NativeNSViewRef pView, GLint cRects, const GLint *paRects)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewSetVisibleRegion: pView=%p cRects=%d paRects=%p)\n", (void *)pView, cRects, (void const *)paRects));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome [(OverlayView *)pView setVisibleRegions:cRects paRects:paRects];
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome COCOA_LOG_FLOW(("cocoaViewSetVisibleRegion: returns\n"));
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome * VMSVGA3D interface.
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas SoomeVMSVGA3D_DECL(void) vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLContextRef pSharedCtx,
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome cocoaGLCtxCreate(ppCtx, CR_ALPHA_BIT | CR_DEPTH_BIT | CR_DOUBLE_BIT | (fOtherProfile ? VMSVGA3D_NON_DEFAULT_PROFILE_BIT : 0),
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas SoomeVMSVGA3D_DECL(void) vmsvga3dCocoaDestroyContext(NativeNSOpenGLContextRef pCtx)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas SoomeVMSVGA3D_DECL(void) vmsvga3dCocoaCreateView(NativeNSViewRef *ppView, NativeNSViewRef pParentView)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome cocoaViewCreate(ppView, NULL, pParentView, 0 /* fVisParams - ignored */);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas SoomeVMSVGA3D_DECL(void) vmsvga3dCocoaDestroyView(NativeNSViewRef pView)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas SoomeVMSVGA3D_DECL(void) vmsvga3dCocoaViewSetPosition(NativeNSViewRef pView, NativeNSViewRef pParentView, int x, int y)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome cocoaViewSetPosition(pView, pParentView, x, y);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas SoomeVMSVGA3D_DECL(void) vmsvga3dCocoaViewSetSize(NativeNSViewRef pView, int w, int h)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas SoomeVMSVGA3D_DECL(void) vmsvga3dCocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx)
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas Soome Assert(!pView || [(OverlayView *)pView glCtx] == pCtx || [(OverlayView *)pView glCtx] == nil);
afc2ba1deb75b323afde536f2dd18bcafdaa308dToomas SoomeVMSVGA3D_DECL(void) vmsvga3dCocoaSwapBuffers(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx)