packspu_context.c revision 31826dacef766ea4c6fb5e9059553c93e41e9d2d
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync/* Copyright (c) 2001, Stanford University
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * All rights reserved
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync *
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * See the file LICENSE.txt for information on redistributing this software.
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#include "packspu.h"
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#include "cr_mem.h"
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#include "cr_packfunctions.h"
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#include "cr_string.h"
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#include "packspu_proto.h"
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#define MAGIC_OFFSET 3000
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync/*
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * Allocate a new ThreadInfo structure, setup a connection to the
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * server, allocate/init a packer context, bind this ThreadInfo to
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * the calling thread with crSetTSD().
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * We'll always call this function at least once even if we're not
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * using threads.
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync */
9562e2d410460d8fae06fa24297f172fee1d1995vboxsyncThreadInfo *packspuNewThread( unsigned long id )
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync{
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync ThreadInfo *thread;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#ifdef CHROMIUM_THREADSAFE
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crLockMutex(&_PackMutex);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#else
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync CRASSERT(pack_spu.numThreads == 0);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#endif
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync CRASSERT(pack_spu.numThreads < MAX_THREADS);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync thread = &(pack_spu.thread[pack_spu.numThreads]);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync thread->id = id;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync thread->currentContext = NULL;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync /* connect to the server */
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync thread->netServer.name = crStrdup( pack_spu.name );
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync thread->netServer.buffer_size = pack_spu.buffer_size;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (pack_spu.numThreads == 0) {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync packspuConnectToServer( &(thread->netServer) );
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (!thread->netServer.conn) {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync return NULL;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync pack_spu.swap = thread->netServer.conn->swap;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync else {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync /* a new pthread */
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crNetNewClient(pack_spu.thread[0].netServer.conn, &(thread->netServer));
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync CRASSERT(thread->netServer.conn);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync /* packer setup */
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync CRASSERT(thread->packer == NULL);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync thread->packer = crPackNewContext( pack_spu.swap );
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync CRASSERT(thread->packer);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crPackInitBuffer( &(thread->buffer), crNetAlloc(thread->netServer.conn),
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync thread->netServer.conn->buffer_size, thread->netServer.conn->mtu );
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync crPackSetBuffer( thread->packer, &thread->buffer );
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync crPackFlushFunc( thread->packer, packspuFlush );
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync crPackFlushArg( thread->packer, (void *) thread );
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync crPackSendHugeFunc( thread->packer, packspuHuge );
0c94df02222ed175411e5363dd39658f2fb1df41vboxsync crPackSetContext( thread->packer );
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#ifdef CHROMIUM_THREADSAFE
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crSetTSD(&_PackTSD, thread);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#endif
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync pack_spu.numThreads++;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#ifdef CHROMIUM_THREADSAFE
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crUnlockMutex(&_PackMutex);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#endif
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync return thread;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync}
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsyncGLint PACKSPU_APIENTRY
9562e2d410460d8fae06fa24297f172fee1d1995vboxsyncpackspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync{
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync int writeback = 1;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync GLint serverCtx = (GLint) -1;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync int slot;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#ifdef CHROMIUM_THREADSAFE
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync crLockMutex(&_PackMutex);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#endif
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (shareCtx > 0) {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync /* translate to server ctx id */
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync shareCtx -= MAGIC_OFFSET;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (shareCtx >= 0 && shareCtx < pack_spu.numContexts) {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync shareCtx = pack_spu.context[shareCtx].serverCtx;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync crPackSetContext( pack_spu.thread[0].packer );
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync /* Pack the command */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (pack_spu.swap)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync crPackCreateContextSWAP( dpyName, visual, shareCtx, &serverCtx, &writeback );
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync else
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crPackCreateContext( dpyName, visual, shareCtx, &serverCtx, &writeback );
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync /* Flush buffer and get return value */
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync packspuFlush( &(pack_spu.thread[0]) );
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (!(pack_spu.thread[0].netServer.conn->actual_network))
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync /* HUMUNGOUS HACK TO MATCH SERVER NUMBERING
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync *
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * The hack exists solely to make file networking work for now. This
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * is totally gross, but since the server expects the numbers to start
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * from 5000, we need to write them out this way. This would be
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * marginally less gross if the numbers (500 and 5000) were maybe
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * some sort of #define'd constants somewhere so the client and the
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * server could be aware of how each other were numbering things in
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * cases like file networking where they actually
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * care.
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync *
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * -Humper
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync *
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync */
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync serverCtx = 5000;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync else {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync while (writeback)
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crNetRecv();
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (pack_spu.swap) {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync serverCtx = (GLint) SWAP32(serverCtx);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (serverCtx < 0) {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#ifdef CHROMIUM_THREADSAFE
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crUnlockMutex(&_PackMutex);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#endif
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crWarning("Failure in packspu_CreateContext");
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync return -1; /* failed */
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* find an empty context slot */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync for (slot = 0; slot < pack_spu.numContexts; slot++) {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (!pack_spu.context[slot].clientState) {
0c94df02222ed175411e5363dd39658f2fb1df41vboxsync /* found empty slot */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync break;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (slot == pack_spu.numContexts) {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync pack_spu.numContexts++;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Fill in the new context info */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* XXX fix-up sharedCtx param here */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pack_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync pack_spu.context[slot].serverCtx = serverCtx;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#ifdef CHROMIUM_THREADSAFE
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crUnlockMutex(&_PackMutex);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#endif
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return MAGIC_OFFSET + slot;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsyncvoid PACKSPU_APIENTRY packspu_DestroyContext( GLint ctx )
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync{
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync const int slot = ctx - MAGIC_OFFSET;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync ContextInfo *context;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync GET_THREAD(thread);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync CRASSERT(slot >= 0);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync CRASSERT(slot < pack_spu.numContexts);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync CRASSERT(thread);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync context = &(pack_spu.context[slot]);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (pack_spu.swap)
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crPackDestroyContextSWAP( context->serverCtx );
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync else
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crPackDestroyContext( context->serverCtx );
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync crStateDestroyContext( context->clientState );
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync context->clientState = NULL;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync context->serverCtx = 0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (thread->currentContext == context) {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync thread->currentContext = NULL;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crStateMakeCurrent( NULL );
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsyncvoid PACKSPU_APIENTRY packspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx )
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync{
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync GET_THREAD(thread);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync GLint serverCtx;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync ContextInfo *newCtx;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
0c94df02222ed175411e5363dd39658f2fb1df41vboxsync if (!thread) {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync thread = packspuNewThread( crThreadID() );
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync CRASSERT(thread);
0c94df02222ed175411e5363dd39658f2fb1df41vboxsync CRASSERT(thread->packer);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (ctx) {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync const int slot = ctx - MAGIC_OFFSET;
0c94df02222ed175411e5363dd39658f2fb1df41vboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync CRASSERT(slot >= 0);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync CRASSERT(slot < pack_spu.numContexts);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
0c94df02222ed175411e5363dd39658f2fb1df41vboxsync newCtx = &pack_spu.context[slot];
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync CRASSERT(newCtx->clientState); /* verify valid */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync thread->currentContext = newCtx;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync crPackSetContext( thread->packer );
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync crStateMakeCurrent( newCtx->clientState );
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync serverCtx = pack_spu.context[slot].serverCtx;
0c94df02222ed175411e5363dd39658f2fb1df41vboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync else {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync thread->currentContext = NULL;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync crStateMakeCurrent( NULL );
0c94df02222ed175411e5363dd39658f2fb1df41vboxsync newCtx = NULL;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync serverCtx = 0;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (pack_spu.swap)
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crPackMakeCurrentSWAP( window, nativeWindow, serverCtx );
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync else
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync crPackMakeCurrent( window, nativeWindow, serverCtx );
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync GET_THREAD(t);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync (void) t;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync CRASSERT(t);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync