packspu_misc.c revision 4001d4f95345a4d3dd2a975a325d389d2300d010
2521N/A/* Copyright (c) 2001, Stanford University
2521N/A * All rights reserved
2521N/A *
2521N/A * See the file LICENSE.txt for information on redistributing this software.
2521N/A */
2521N/A
2892N/A#include "cr_packfunctions.h"
2521N/A#include "packspu.h"
2521N/A#include "packspu_proto.h"
2892N/A#include "cr_mem.h"
2892N/A
2892N/Avoid PACKSPU_APIENTRY packspu_ChromiumParametervCR(GLenum target, GLenum type, GLsizei count, const GLvoid *values)
2892N/A{
2892N/A
2892N/A CRMessage msg;
2892N/A int len;
2521N/A
2521N/A GET_THREAD(thread);
2521N/A
2521N/A
2521N/A switch(target)
2521N/A {
2521N/A case GL_GATHER_PACK_CR:
2521N/A /* flush the current pack buffer */
2521N/A packspuFlush( (void *) thread );
2521N/A
2521N/A /* the connection is thread->server.conn */
2521N/A msg.header.type = CR_MESSAGE_GATHER;
2521N/A msg.gather.offset = 69;
2521N/A len = sizeof(CRMessageGather);
2521N/A crNetSend(thread->netServer.conn, NULL, &msg, len);
2521N/A break;
2521N/A
2521N/A default:
3998N/A if (pack_spu.swap)
2521N/A crPackChromiumParametervCRSWAP(target, type, count, values);
2521N/A else
3998N/A crPackChromiumParametervCR(target, type, count, values);
3998N/A }
3998N/A
3998N/A
3998N/A}
3998N/A
2521N/AGLboolean packspuSyncOnFlushes()
2892N/A{
3998N/A GLint buffer;
2892N/A
2892N/A /*Seems to still cause issues, always sync for now*/
2892N/A return 1;
2892N/A
3998N/A crStateGetIntegerv(GL_DRAW_BUFFER, &buffer);
3998N/A /*Usually buffer==GL_BACK, so put this extra check to simplify boolean eval on runtime*/
3998N/A return (buffer != GL_BACK)
2892N/A && (buffer == GL_FRONT_LEFT
2892N/A || buffer == GL_FRONT_RIGHT
2892N/A || buffer == GL_FRONT
2892N/A || buffer == GL_FRONT_AND_BACK
2892N/A || buffer == GL_LEFT
2892N/A || buffer == GL_RIGHT);
2892N/A}
2892N/A
2892N/Avoid PACKSPU_APIENTRY packspu_DrawBuffer(GLenum mode)
2892N/A{
2892N/A GLboolean hadtoflush;
3998N/A
3998N/A hadtoflush = packspuSyncOnFlushes();
2892N/A
2892N/A crStateDrawBuffer(mode);
2521N/A crPackDrawBuffer(mode);
2521N/A
2521N/A if (hadtoflush && !packspuSyncOnFlushes())
2521N/A packspu_Flush();
2521N/A}
2521N/A
2521N/Avoid PACKSPU_APIENTRY packspu_Finish( void )
2521N/A{
2521N/A GET_THREAD(thread);
2521N/A GLint writeback = CRPACKSPU_IS_WDDM_CRHGSMI() ? 1 : pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;
2521N/A
2521N/A if (pack_spu.swap)
2521N/A {
2521N/A crPackFinishSWAP();
2521N/A }
3998N/A else
3998N/A {
2663N/A crPackFinish();
2521N/A }
2521N/A
2521N/A if (packspuSyncOnFlushes())
2521N/A {
2521N/A if (writeback)
2521N/A {
2521N/A if (pack_spu.swap)
2521N/A crPackWritebackSWAP(&writeback);
2521N/A else
2521N/A crPackWriteback(&writeback);
2521N/A
2521N/A packspuFlush( (void *) thread );
3998N/A
3998N/A CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
2521N/A }
2521N/A }
2892N/A}
2521N/A
2521N/Avoid PACKSPU_APIENTRY packspu_Flush( void )
3998N/A{
2521N/A GET_THREAD(thread);
2521N/A int writeback=1;
2521N/A int found=0;
2521N/A
2521N/A if (!thread->bInjectThread)
2521N/A {
2521N/A crPackFlush();
2521N/A if (packspuSyncOnFlushes())
3998N/A {
3998N/A crPackWriteback(&writeback);
2521N/A packspuFlush( (void *) thread );
2521N/A CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
2521N/A }
2521N/A }
2521N/A else
2521N/A {
3998N/A int i;
3998N/A
2521N/A crLockMutex(&_PackMutex);
2521N/A
2521N/A /*Make sure we process commands in order they should appear, so flush other threads first*/
2521N/A for (i=0; i<MAX_THREADS; ++i)
2521N/A {
3998N/A if (pack_spu.thread[i].inUse
2521N/A && (thread != &pack_spu.thread[i]) && pack_spu.thread[i].netServer.conn
2521N/A && pack_spu.thread[i].packer && pack_spu.thread[i].packer->currentBuffer)
2521N/A {
2521N/A packspuFlush((void *) &pack_spu.thread[i]);
2521N/A
2521N/A if (pack_spu.thread[i].netServer.conn->u32ClientID == thread->netServer.conn->u32InjectClientID)
2521N/A {
2521N/A found=1;
2521N/A }
2521N/A
2521N/A }
2521N/A }
2521N/A
2521N/A if (!found)
2521N/A {
2521N/A /*Thread we're supposed to inject commands for has been detached,
2521N/A so there's nothing to sync with and we should just pass commands through our own connection.
2521N/A */
2521N/A thread->netServer.conn->u32InjectClientID=0;
2521N/A }
2521N/A
2521N/A packspuFlush((void *) thread);
2892N/A
2521N/A crUnlockMutex(&_PackMutex);
2521N/A }
2521N/A}
2521N/A
2892N/Avoid PACKSPU_APIENTRY packspu_VBoxWindowDestroy( GLint con, GLint window )
2892N/A{
2892N/A if (CRPACKSPU_IS_WDDM_CRHGSMI())
2521N/A {
2521N/A GET_THREAD(thread);
2521N/A if (con)
2521N/A {
2521N/A CRPackContext * curPacker = crPackGetContext();
2521N/A CRASSERT(!thread || !thread->bInjectThread);
2521N/A thread = GET_THREAD_VAL_ID(con);
2521N/A crPackSetContext(thread->packer);
2521N/A crPackWindowDestroy(window);
2892N/A if (curPacker != thread->packer)
2892N/A crPackSetContext(curPacker);
2892N/A return;
2892N/A }
2521N/A CRASSERT(thread);
2521N/A CRASSERT(thread->bInjectThread);
3998N/A }
3998N/A crPackWindowDestroy(window);
3998N/A}
3998N/A
2925N/AGLint PACKSPU_APIENTRY packspu_VBoxWindowCreate( GLint con, const char *dpyName, GLint visBits )
2925N/A{
2925N/A GET_THREAD(thread);
2925N/A static int num_calls = 0;
2521N/A int writeback = CRPACKSPU_IS_WDDM_CRHGSMI() ? 1 : pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;
2925N/A GLint return_val = (GLint) 0;
3998N/A ThreadInfo *curThread = thread;
3998N/A GLint retVal;
3998N/A
3998N/A if (CRPACKSPU_IS_WDDM_CRHGSMI())
3998N/A {
3998N/A if (!con)
3998N/A {
2892N/A crError("connection expected!");
2521N/A return 0;
2892N/A }
3998N/A thread = GET_THREAD_VAL_ID(con);
2892N/A }
2892N/A else
3998N/A {
3998N/A CRASSERT(!con);
3998N/A if (!thread) {
3998N/A thread = packspuNewThread(
3998N/A#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
2892N/A NULL
2892N/A#endif
2892N/A );
2892N/A }
2892N/A }
2892N/A CRASSERT(thread);
2892N/A CRASSERT(thread->packer);
2892N/A CRASSERT(crPackGetContext() == (curThread ? curThread->packer : NULL));
3998N/A
3998N/A crPackSetContext(thread->packer);
3998N/A
3998N/A if (pack_spu.swap)
2521N/A {
2521N/A crPackWindowCreateSWAP( dpyName, visBits, &return_val, &writeback );
2892N/A }
2892N/A else
2892N/A {
2892N/A crPackWindowCreate( dpyName, visBits, &return_val, &writeback );
2892N/A }
3998N/A packspuFlush(thread);
2892N/A if (!(thread->netServer.conn->actual_network))
2892N/A {
2892N/A retVal = num_calls++;
2892N/A }
2892N/A else
2892N/A {
2892N/A CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
2892N/A if (pack_spu.swap)
2892N/A {
2892N/A return_val = (GLint) SWAP32(return_val);
2892N/A }
2521N/A retVal = return_val;
3998N/A }
3998N/A
3998N/A if (CRPACKSPU_IS_WDDM_CRHGSMI())
3998N/A {
3998N/A if (thread != curThread)
3998N/A {
3998N/A if (curThread)
3998N/A crPackSetContext(curThread->packer);
3998N/A else
3998N/A crPackSetContext(NULL);
3998N/A }
3998N/A }
3998N/A
3998N/A return retVal;
3998N/A}
3998N/A
2521N/AGLint PACKSPU_APIENTRY packspu_WindowCreate( const char *dpyName, GLint visBits )
2521N/A{
2892N/A return packspu_VBoxWindowCreate( 0, dpyName, visBits );
2521N/A}
2521N/A
2892N/AGLboolean PACKSPU_APIENTRY
2892N/Apackspu_AreTexturesResident( GLsizei n, const GLuint * textures,
2892N/A GLboolean * residences )
2892N/A{
2892N/A GET_THREAD(thread);
2892N/A int writeback = 1;
2892N/A GLboolean return_val = GL_TRUE;
2521N/A GLsizei i;
2521N/A
2521N/A if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
2521N/A {
2521N/A crError( "packspu_AreTexturesResident doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
2521N/A }
2521N/A
2521N/A if (pack_spu.swap)
2521N/A {
2521N/A crPackAreTexturesResidentSWAP( n, textures, residences, &return_val, &writeback );
2892N/A }
3998N/A else
3998N/A {
3998N/A crPackAreTexturesResident( n, textures, residences, &return_val, &writeback );
3998N/A }
2892N/A packspuFlush( (void *) thread );
2892N/A
3998N/A CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
3998N/A
2892N/A /* Since the Chromium packer/unpacker can't return both 'residences'
2892N/A * and the function's return value, compute the return value here.
2892N/A */
2892N/A for (i = 0; i < n; i++) {
2892N/A if (!residences[i]) {
2892N/A return_val = GL_FALSE;
2892N/A break;
2892N/A }
2892N/A }
2892N/A
2892N/A return return_val;
2892N/A}
2892N/A
2892N/A
3998N/AGLboolean PACKSPU_APIENTRY
3998N/Apackspu_AreProgramsResidentNV( GLsizei n, const GLuint * ids,
3998N/A GLboolean * residences )
3998N/A{
3998N/A GET_THREAD(thread);
2892N/A int writeback = 1;
2892N/A GLboolean return_val = GL_TRUE;
2892N/A GLsizei i;
2892N/A
2892N/A if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
2892N/A {
2892N/A crError( "packspu_AreProgramsResidentNV doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
2892N/A }
2892N/A if (pack_spu.swap)
2521N/A {
2521N/A crPackAreProgramsResidentNVSWAP( n, ids, residences, &return_val, &writeback );
2521N/A }
2521N/A else
2521N/A {
2521N/A crPackAreProgramsResidentNV( n, ids, residences, &return_val, &writeback );
2521N/A }
2521N/A packspuFlush( (void *) thread );
2521N/A
2521N/A CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
2521N/A
2521N/A /* Since the Chromium packer/unpacker can't return both 'residences'
2521N/A * and the function's return value, compute the return value here.
2521N/A */
2521N/A for (i = 0; i < n; i++) {
2521N/A if (!residences[i]) {
2521N/A return_val = GL_FALSE;
2521N/A break;
2521N/A }
2521N/A }
2521N/A
2521N/A return return_val;
2521N/A}
2521N/A
2521N/Avoid PACKSPU_APIENTRY packspu_GetPolygonStipple( GLubyte * mask )
2521N/A{
2521N/A GET_THREAD(thread);
2521N/A int writeback = 1;
2521N/A
2521N/A if (pack_spu.swap)
2521N/A {
2892N/A crPackGetPolygonStippleSWAP( mask, &writeback );
2521N/A }
2521N/A else
2521N/A {
2521N/A crPackGetPolygonStipple( mask, &writeback );
2892N/A }
2521N/A
2521N/A#ifdef CR_ARB_pixel_buffer_object
2521N/A if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
2521N/A#endif
2892N/A {
2892N/A packspuFlush( (void *) thread );
2892N/A CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
2892N/A }
2892N/A}
2892N/A
2521N/Avoid PACKSPU_APIENTRY packspu_GetPixelMapfv( GLenum map, GLfloat * values )
2521N/A{
2521N/A GET_THREAD(thread);
2521N/A int writeback = 1;
2892N/A
2521N/A if (pack_spu.swap)
2521N/A {
2521N/A crPackGetPixelMapfvSWAP( map, values, &writeback );
2521N/A }
2892N/A else
2892N/A {
2892N/A crPackGetPixelMapfv( map, values, &writeback );
2892N/A }
2892N/A
2892N/A#ifdef CR_ARB_pixel_buffer_object
2892N/A if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
2892N/A#endif
2892N/A {
2892N/A packspuFlush( (void *) thread );
2892N/A CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
2892N/A }
2892N/A}
2892N/A
2892N/Avoid PACKSPU_APIENTRY packspu_GetPixelMapuiv( GLenum map, GLuint * values )
2892N/A{
2892N/A GET_THREAD(thread);
2892N/A int writeback = 1;
2892N/A
2892N/A if (pack_spu.swap)
2892N/A {
2892N/A crPackGetPixelMapuivSWAP( map, values, &writeback );
2892N/A }
2892N/A else
2892N/A {
2892N/A crPackGetPixelMapuiv( map, values, &writeback );
2892N/A }
2892N/A
2892N/A#ifdef CR_ARB_pixel_buffer_object
2892N/A if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
2892N/A#endif
2521N/A {
2521N/A packspuFlush( (void *) thread );
2521N/A CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
2521N/A }
2892N/A}
2521N/A
2892N/Avoid PACKSPU_APIENTRY packspu_GetPixelMapusv( GLenum map, GLushort * values )
2892N/A{
2892N/A GET_THREAD(thread);
2892N/A int writeback = 1;
2892N/A
2892N/A if (pack_spu.swap)
2892N/A {
2892N/A crPackGetPixelMapusvSWAP( map, values, &writeback );
2892N/A }
2892N/A else
3998N/A {
3998N/A crPackGetPixelMapusv( map, values, &writeback );
3998N/A }
3998N/A
2521N/A#ifdef CR_ARB_pixel_buffer_object
2521N/A if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
2892N/A#endif
3998N/A {
3998N/A packspuFlush( (void *) thread );
2892N/A CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
2892N/A }
3998N/A}
2892N/A
2892N/Astatic void packspuFluchOnThreadSwitch(GLboolean fEnable)
2892N/A{
2892N/A GET_THREAD(thread);
2892N/A if (thread->currentContext->fAutoFlush == fEnable)
3998N/A return;
2892N/A
2892N/A thread->currentContext->fAutoFlush = fEnable;
2892N/A thread->currentContext->currentThread = fEnable ? thread : NULL;
2892N/A}
2892N/A
3998N/Avoid PACKSPU_APIENTRY packspu_ChromiumParameteriCR(GLenum target, GLint value)
2892N/A{
2892N/A switch (target)
2892N/A {
2892N/A case GL_FLUSH_ON_THREAD_SWITCH_CR:
2892N/A /* this is a pure packspu state, don't propagate it any further */
2892N/A packspuFluchOnThreadSwitch(value);
2892N/A return;
2892N/A case GL_SHARE_CONTEXT_RESOURCES_CR:
2892N/A crStateShareContext(value);
2892N/A break;
2892N/A case GL_RCUSAGE_TEXTURE_SET_CR:
2892N/A crStateSetTextureUsed(value, GL_TRUE);
2892N/A break;
2892N/A case GL_RCUSAGE_TEXTURE_CLEAR_CR:
2892N/A crStateSetTextureUsed(value, GL_FALSE);
2892N/A break;
2892N/A default:
2892N/A break;
2892N/A }
2892N/A crPackChromiumParameteriCR(target, value);
2892N/A}
2892N/A
2892N/A#ifdef CHROMIUM_THREADSAFE
2892N/AGLint PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(struct VBOXUHGSMI *pHgsmi)
2892N/A{
2892N/A GLint con = 0;
2892N/A int i;
2892N/A GET_THREAD(thread);
2892N/A CRASSERT(!thread);
2892N/A crLockMutex(&_PackMutex);
2892N/A {
2892N/A CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI() || (pack_spu.numThreads>0));
2892N/A CRASSERT(pack_spu.numThreads<MAX_THREADS);
2892N/A for (i=0; i<MAX_THREADS; ++i)
2892N/A {
2892N/A if (!pack_spu.thread[i].inUse)
2892N/A {
2892N/A thread = &pack_spu.thread[i];
2892N/A break;
2892N/A }
2892N/A }
2892N/A CRASSERT(thread);
2892N/A
2892N/A thread->inUse = GL_TRUE;
2892N/A if (!CRPACKSPU_IS_WDDM_CRHGSMI())
2892N/A thread->id = crThreadID();
2892N/A else
2892N/A thread->id = THREAD_OFFSET_MAGIC + i;
2892N/A thread->currentContext = NULL;
2892N/A thread->bInjectThread = GL_TRUE;
2892N/A
2892N/A thread->netServer.name = crStrdup(pack_spu.name);
2892N/A thread->netServer.buffer_size = 64 * 1024;
2892N/A
2892N/A packspuConnectToServer(&(thread->netServer)
2892N/A#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
2892N/A , pHgsmi
2892N/A#endif
2892N/A );
2892N/A CRASSERT(thread->netServer.conn);
2892N/A
2892N/A CRASSERT(thread->packer == NULL);
2892N/A thread->packer = crPackNewContext( pack_spu.swap );
2892N/A CRASSERT(thread->packer);
2892N/A crPackInitBuffer(&(thread->buffer), crNetAlloc(thread->netServer.conn),
2892N/A thread->netServer.conn->buffer_size, thread->netServer.conn->mtu);
2892N/A thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;
2892N/A
2892N/A crPackSetBuffer( thread->packer, &thread->buffer );
2892N/A crPackFlushFunc( thread->packer, packspuFlush );
2892N/A crPackFlushArg( thread->packer, (void *) thread );
2892N/A crPackSendHugeFunc( thread->packer, packspuHuge );
2892N/A crPackSetContext( thread->packer );
2892N/A
2892N/A crSetTSD(&_PackTSD, thread);
2892N/A
2892N/A pack_spu.numThreads++;
2892N/A }
2892N/A crUnlockMutex(&_PackMutex);
2892N/A
2892N/A if (CRPACKSPU_IS_WDDM_CRHGSMI())
2892N/A {
2892N/A CRASSERT(thread->id - THREAD_OFFSET_MAGIC < RT_ELEMENTS(pack_spu.thread)
2892N/A && GET_THREAD_VAL_ID(thread->id) == thread);
2892N/A con = thread->id;
2892N/A }
2892N/A return con;
2892N/A}
2892N/A
3998N/AGLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(GLint con)
3998N/A{
3998N/A GLuint ret;
3998N/A
3998N/A crLockMutex(&_PackMutex);
3998N/A {
3998N/A ThreadInfo *thread = NULL;
3998N/A if (CRPACKSPU_IS_WDDM_CRHGSMI())
3998N/A {
3998N/A if (!con)
3998N/A {
3998N/A crError("connection expected!");
3998N/A return 0;
3998N/A }
3998N/A thread = GET_THREAD_VAL_ID(con);
3998N/A }
3998N/A else
3998N/A {
3998N/A CRASSERT(!con);
3998N/A thread = GET_THREAD_VAL();
3998N/A }
3998N/A CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM);
3998N/A ret = thread->netServer.conn->u32ClientID;
3998N/A }
3998N/A crUnlockMutex(&_PackMutex);
3998N/A
3998N/A return ret;
3998N/A}
3998N/A
void PACKSPU_APIENTRY packspu_VBoxPackSetInjectID(GLuint id)
{
crLockMutex(&_PackMutex);
{
GET_THREAD(thread);
CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM && thread->bInjectThread);
thread->netServer.conn->u32InjectClientID = id;
}
crUnlockMutex(&_PackMutex);
}
void PACKSPU_APIENTRY packspu_VBoxAttachThread()
{
#if 0
int i;
GET_THREAD(thread);
for (i=0; i<MAX_THREADS; ++i)
{
if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i] && thread->id==crThreadID())
{
crError("2nd attach to same thread");
}
}
#endif
crSetTSD(&_PackTSD, NULL);
crStateVBoxAttachThread();
}
void PACKSPU_APIENTRY packspu_VBoxDetachThread()
{
if (CRPACKSPU_IS_WDDM_CRHGSMI())
{
crPackSetContext(NULL);
crSetTSD(&_PackTSD, NULL);
}
else
{
int i;
GET_THREAD(thread);
if (thread)
{
crLockMutex(&_PackMutex);
for (i=0; i<MAX_THREADS; ++i)
{
if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i]
&& thread->id==crThreadID() && thread->netServer.conn)
{
CRASSERT(pack_spu.numThreads>0);
packspuFlush((void *) thread);
if (pack_spu.thread[i].packer)
{
CR_LOCK_PACKER_CONTEXT(thread->packer);
crPackSetContext(NULL);
CR_UNLOCK_PACKER_CONTEXT(thread->packer);
crPackDeleteContext(pack_spu.thread[i].packer);
}
crNetFreeConnection(pack_spu.thread[i].netServer.conn);
pack_spu.numThreads--;
/*note can't shift the array here, because other threads have TLS references to array elements*/
crMemZero(&pack_spu.thread[i], sizeof(ThreadInfo));
crSetTSD(&_PackTSD, NULL);
if (i==pack_spu.idxThreadInUse)
{
for (i=0; i<MAX_THREADS; ++i)
{
if (pack_spu.thread[i].inUse)
{
pack_spu.idxThreadInUse=i;
break;
}
}
}
break;
}
}
for (i=0; i<CR_MAX_CONTEXTS; ++i)
{
ContextInfo *ctx = &pack_spu.context[i];
if (ctx->currentThread == thread)
{
CRASSERT(ctx->fAutoFlush);
ctx->currentThread = NULL;
}
}
crUnlockMutex(&_PackMutex);
}
}
crStateVBoxDetachThread();
}
#ifdef WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
{
(void) lpvReserved;
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
crInitMutex(&_PackMutex);
break;
}
case DLL_PROCESS_DETACH:
{
crFreeMutex(&_PackMutex);
crNetTearDown();
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
default:
break;
}
return TRUE;
}
#endif
#else /*ifdef CHROMIUM_THREADSAFE*/
GLint PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(struct VBOXUHGSMI *pHgsmi)
{
}
GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(GLint con)
{
return 0;
}
void PACKSPU_APIENTRY packspu_VBoxPackSetInjectID(GLuint id)
{
(void) id;
}
void PACKSPU_APIENTRY packspu_VBoxPackAttachThread()
{
}
void PACKSPU_APIENTRY packspu_VBoxPackDetachThread()
{
}
#endif /*CHROMIUM_THREADSAFE*/