Sunteți pe pagina 1din 7

/* $Id$ */

/** @file
* VBox OpenGL windows ICD driver functions
*/
/*
* Copyright (C) 2006-2016 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include
#include
#include
#include
#include

"cr_error.h"
"icd_drv.h"
"cr_gl.h"
"stub.h"
"cr_mem.h"

#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)


# include <VBox/VBoxCrHgsmi.h>
# include <VBox/VBoxUhgsmi.h>
#endif
#include <iprt/win/windows.h>
//TODO: consider
/* We can modify chronium dispatch table functions order to match the one requir
ed by ICD,
* but it'd render us incompatible with other chromium SPUs and require more cha
nges.
* In current state, we can use unmodified binary chromium SPUs. Question is do
we need it?
*/
#define GL_FUNC(func) cr_gl##func
static ICDTABLE icdTable = { 336, {
#define ICD_ENTRY(func) (PROC)GL_FUNC(func),
#include "VBoxICDList.h"
#undef ICD_ENTRY
} };
/* Currently host part will misbehave re-creating context with proper visual bit
s
* if contexts with alternative visual bits is requested.
* For now we just report a superset of all visual bits to avoid that.
* Better to it on the host side as well?
* We could also implement properly multiple pixel formats,
* which should be done by implementing offscreen rendering or multiple host con
texts.
* */
#define VBOX_CROGL_USE_VBITS_SUPERSET
#ifdef VBOX_CROGL_USE_VBITS_SUPERSET
static GLuint desiredVisual = CR_RGB_BIT | CR_ALPHA_BIT | CR_DEPTH_BIT | CR_STEN

CIL_BIT | CR_ACCUM_BIT | CR_DOUBLE_BIT;


#else
static GLuint desiredVisual = CR_RGB_BIT;
#endif
#ifndef VBOX_CROGL_USE_VBITS_SUPERSET
/**
* Compute a mask of CR_*_BIT flags which reflects the attributes of
* the pixel format of the given hdc.
*/
static GLuint ComputeVisBits( HDC hdc )
{
PIXELFORMATDESCRIPTOR pfd;
int iPixelFormat;
GLuint b = 0;
iPixelFormat = GetPixelFormat( hdc );
DescribePixelFormat( hdc, iPixelFormat, sizeof(pfd), &pfd );
if (pfd.cDepthBits > 0)
b |= CR_DEPTH_BIT;
if (pfd.cAccumBits > 0)
b |= CR_ACCUM_BIT;
if (pfd.cColorBits > 8)
b |= CR_RGB_BIT;
if (pfd.cStencilBits > 0)
b |= CR_STENCIL_BIT;
if (pfd.cAlphaBits > 0)
b |= CR_ALPHA_BIT;
if (pfd.dwFlags & PFD_DOUBLEBUFFER)
b |= CR_DOUBLE_BIT;
if (pfd.dwFlags & PFD_STEREO)
b |= CR_STEREO_BIT;
return b;
}
#endif
void APIENTRY DrvReleaseContext(HGLRC hglrc)
{
CR_DDI_PROLOGUE();
/*crDebug( "DrvReleaseContext(0x%x) called", hglrc );*/
stubMakeCurrent( NULL, NULL );
}
BOOL APIENTRY DrvValidateVersion(DWORD version)
{
CR_DDI_PROLOGUE();
if (stubInit()) {
crDebug("DrvValidateVersion %x -> TRUE\n", version);
return TRUE;
}
crDebug("DrvValidateVersion %x -> FALSE, going to use system default opengl3
2.dll\n", version);
return FALSE;
}
//we're not going to change icdTable at runtime, so callback is unused

PICDTABLE APIENTRY DrvSetContext(HDC hdc, HGLRC hglrc, void *callback)


{
ContextInfo *pContext;
WindowInfo *pWindowInfo;
BOOL ret = false;
CR_DDI_PROLOGUE();
(void) (callback);
crHashtableLock(stub.windowTable);
crHashtableLock(stub.contextTable);
pContext = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned lo
ng) hglrc);
if (pContext)
{
pWindowInfo = stubGetWindowInfo(hdc);
if (pWindowInfo)
ret = stubMakeCurrent(pWindowInfo, pContext);
else
crError("no window info available.");
}
else
crError("No context found.");
crHashtableUnlock(stub.contextTable);
crHashtableUnlock(stub.windowTable);
return ret ? &icdTable : NULL;
}
BOOL APIENTRY DrvSetPixelFormat(HDC hdc, int iPixelFormat)
{
CR_DDI_PROLOGUE();
crDebug( "DrvSetPixelFormat(0x%x, %i) called.", hdc, iPixelFormat );
if ( (iPixelFormat<1) || (iPixelFormat>2) ) {
crError( "wglSetPixelFormat: iPixelFormat=%d?", iPixelFormat );
}
return 1;
}
HGLRC APIENTRY DrvCreateContext(HDC hdc)
{
char dpyName[MAX_DPY_NAME];
ContextInfo *context;
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
PVBOXUHGSMI pHgsmi = NULL;
#endif
CR_DDI_PROLOGUE();
crDebug( "DrvCreateContext(0x%x) called.", hdc);
stubInit();
CRASSERT(stub.contextTable);

sprintf(dpyName, "%d", hdc);


#ifndef VBOX_CROGL_USE_VBITS_SUPERSET
if (stub.haveNativeOpenGL)
desiredVisual |= ComputeVisBits( hdc );
#endif
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
pHgsmi = VBoxCrHgsmiCreate();
#endif
context = stubNewContext(dpyName, desiredVisual, UNDECIDED, 0
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
, pHgsmi
#endif
);
if (!context)
return 0;
return (HGLRC) context->id;
}
HGLRC APIENTRY DrvCreateLayerContext(HDC hdc, int iLayerPlane)
{
CR_DDI_PROLOGUE();
crDebug( "DrvCreateLayerContext(0x%x, %i) called.", hdc, iLayerPlane);
//We don't support more than 1 layers.
if (iLayerPlane == 0) {
return DrvCreateContext(hdc);
} else {
crError( "DrvCreateLayerContext (%x,%x): unsupported", hdc, iLayerPlane)
;
return NULL;
}
}
BOOL APIENTRY DrvDescribeLayerPlane(HDC hdc,int iPixelFormat,
int iLayerPlane, UINT nBytes,
LPLAYERPLANEDESCRIPTOR plpd)
{
CR_DDI_PROLOGUE();
crWarning( "DrvDescribeLayerPlane: unimplemented" );
CRASSERT(false);
return 0;
}
int APIENTRY DrvGetLayerPaletteEntries(HDC hdc, int iLayerPlane,
int iStart, int cEntries,
COLORREF *pcr)
{
CR_DDI_PROLOGUE();
crWarning( "DrvGetLayerPaletteEntries: unsupported" );
CRASSERT(false);
return 0;
}
int APIENTRY DrvDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPI
XELFORMATDESCRIPTOR pfd)
{
CR_DDI_PROLOGUE();

if ( !pfd ) {
return 2;
}
if ( nBytes != sizeof(*pfd) ) {
crWarning( "DrvDescribePixelFormat: nBytes=%u?", nBytes );
return 2;
}
if (iPixelFormat==1)
{
crMemZero(pfd, sizeof(*pfd));
pfd->nSize
pfd->nVersion
pfd->dwFlags

pfd->dwFlags
happy */
pfd->iPixelType
pfd->cColorBits
pfd->cRedBits
pfd->cRedShift
pfd->cGreenBits
pfd->cGreenShift
pfd->cBlueBits
pfd->cBlueShift
pfd->cAlphaBits
pfd->cAlphaShift
pfd->cAccumBits
pfd->cAccumRedBits
pfd->cAccumGreenBits
pfd->cAccumBlueBits
pfd->cAccumAlphaBits
pfd->cDepthBits
pfd->cStencilBits
pfd->cAuxBuffers
pfd->iLayerType
pfd->bReserved
pfd->dwLayerMask
pfd->dwVisibleMask
pfd->dwDamageMask

= sizeof(*pfd);
= 1;
= (PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER);
|= 0x8000; /* <- Needed for VSG Open Inventor to be
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

PFD_TYPE_RGBA;
32;
8;
24;
8;
16;
8;
8;
8;
0;
0;
0;
0;
0;
0;
32;
8;
0;
PFD_MAIN_PLANE;
0;
0;
0;
0;

}
else
{
crMemZero(pfd, sizeof(*pfd));
pfd->nVersion
= 1;
pfd->dwFlags
= (PFD_DRAW_TO_WINDOW|
PFD_SUPPORT_OPENGL);
pfd->iPixelType
pfd->cColorBits
pfd->cRedBits
pfd->cRedShift
pfd->cGreenBits
pfd->cGreenShift
pfd->cBlueBits

=
=
=
=
=
=
=

PFD_TYPE_RGBA;
32;
8;
16;
8;
8;
8;

pfd->cBlueShift
pfd->cAlphaBits
pfd->cAlphaShift
pfd->cAccumBits
pfd->cAccumRedBits
pfd->cAccumGreenBits
pfd->cAccumBlueBits
pfd->cAccumAlphaBits
pfd->cDepthBits
pfd->cStencilBits
pfd->cAuxBuffers
pfd->iLayerType
pfd->bReserved
pfd->dwLayerMask
pfd->dwVisibleMask
pfd->dwDamageMask

=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

0;
0;
0;
64;
16;
16;
16;
0;
16;
8;
0;
PFD_MAIN_PLANE;
0;
0;
0;
0;

}
/* the max PFD index */
return 2;
}
BOOL APIENTRY DrvDeleteContext(HGLRC hglrc)
{
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
ContextInfo *pContext;
PVBOXUHGSMI pHgsmi = NULL;
#endif
CR_DDI_PROLOGUE();
crDebug( "DrvDeleteContext(0x%x) called", hglrc );
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
crHashtableLock(stub.contextTable);
pContext = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned lo
ng) hglrc);
if (pContext)
pHgsmi = pContext->pHgsmi;
crHashtableUnlock(stub.contextTable);
#endif
stubDestroyContext( (unsigned long) hglrc );
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
if (pHgsmi)
VBoxCrHgsmiDestroy(pHgsmi);
#endif
return true;
}
BOOL APIENTRY DrvCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
{
CR_DDI_PROLOGUE();
crWarning( "DrvCopyContext: unsupported" );
return 0;
}

DECLEXPORT(BOOL) WINAPI wglShareLists_prox( HGLRC hglrc1, HGLRC hglrc2 );


BOOL APIENTRY DrvShareLists(HGLRC hglrc1, HGLRC hglrc2)
{
return wglShareLists_prox(hglrc1, hglrc2);
}
int APIENTRY DrvSetLayerPaletteEntries(HDC hdc, int iLayerPlane,
int iStart, int cEntries,
CONST COLORREF *pcr)
{
CR_DDI_PROLOGUE();
crWarning( "DrvSetLayerPaletteEntries: unsupported" );
return 0;
}
BOOL APIENTRY DrvRealizeLayerPalette(HDC hdc, int iLayerPlane, BOOL bRealize)
{
CR_DDI_PROLOGUE();
crWarning( "DrvRealizeLayerPalette: unsupported" );
return 0;
}
BOOL APIENTRY DrvSwapLayerBuffers(HDC hdc, UINT fuPlanes)
{
CR_DDI_PROLOGUE();
if (fuPlanes == 1)
{
return DrvSwapBuffers(hdc);
}
else
{
crWarning( "DrvSwapLayerBuffers: unsupported" );
CRASSERT(false);
return 0;
}
}
BOOL APIENTRY DrvSwapBuffers(HDC hdc)
{
WindowInfo *window;
CR_DDI_PROLOGUE();
/*crDebug( "DrvSwapBuffers(0x%x) called", hdc );*/
window = stubGetWindowInfo(hdc);
stubSwapBuffers( window, 0 );
return 1;
}

S-ar putea să vă placă și