Esempio n. 1
0
int crPackCanHoldBuffer( const CRPackBuffer *src )
{
	const int num_data = crPackNumData(src);
	const int num_opcode = crPackNumOpcodes(src);
    int res;
	CR_GET_PACKER_CONTEXT(pc);
    CR_LOCK_PACKER_CONTEXT(pc);
	res = crPackCanHoldOpcode( pc, num_opcode, num_data );
    CR_UNLOCK_PACKER_CONTEXT(pc);
    return res;
}
Esempio n. 2
0
void crPackAppendBuffer( const CRPackBuffer *src )
{
	CR_GET_PACKER_CONTEXT(pc);
	const int num_data = crPackNumData(src);
	const int num_opcode = crPackNumOpcodes(src);

	CRASSERT(num_data >= 0);
	CRASSERT(num_opcode >= 0);

    CR_LOCK_PACKER_CONTEXT(pc);

	/* don't append onto ourself! */
	CRASSERT(pc->currentBuffer);
	CRASSERT(pc->currentBuffer != src);

	if (!crPackCanHoldBuffer(src))
	{
		if (src->holds_BeginEnd)
		{
			crWarning( "crPackAppendBuffer: overflowed the destination!" );
            CR_UNLOCK_PACKER_CONTEXT(pc);
			return;
		}
		else
        {
			crError( "crPackAppendBuffer: overflowed the destination!" );
            CR_UNLOCK_PACKER_CONTEXT(pc);
        }
	}

	/* Copy the buffer data/operands which are at the head of the buffer */
	crMemcpy( pc->buffer.data_current, src->data_start, num_data );
	pc->buffer.data_current += num_data;

	/* Copy the buffer opcodes which are at the tail of the buffer */
	CRASSERT( pc->buffer.opcode_current - num_opcode >= pc->buffer.opcode_end );
	crMemcpy( pc->buffer.opcode_current + 1 - num_opcode, src->opcode_current + 1,
			num_opcode );
	pc->buffer.opcode_current -= num_opcode;
	pc->buffer.holds_BeginEnd |= src->holds_BeginEnd;
	pc->buffer.in_BeginEnd = src->in_BeginEnd;
	pc->buffer.holds_List |= src->holds_List;
    CR_UNLOCK_PACKER_CONTEXT(pc);
}
Esempio n. 3
0
void
crPackAppendBoundedBuffer( const CRPackBuffer *src, const CRrecti *bounds )
{
	CR_GET_PACKER_CONTEXT(pc);
	const GLbyte *payload = (const GLbyte *) src->opcode_current + 1;
	const int num_opcodes = crPackNumOpcodes(src);
	const int length = src->data_current - src->opcode_current - 1;

	CRASSERT(pc);
    CR_LOCK_PACKER_CONTEXT(pc);
	CRASSERT(pc->currentBuffer);
	CRASSERT(pc->currentBuffer != src);

	/*
	 * payload points to the block of opcodes immediately followed by operands.
	 */

	if ( !crPackCanHoldBoundedBuffer( src ) )
	{
		if (src->holds_BeginEnd)
		{
			crWarning( "crPackAppendBoundedBuffer: overflowed the destination!" );
            CR_UNLOCK_PACKER_CONTEXT(pc);
			return;
		}
		else
        {
			crError( "crPackAppendBoundedBuffer: overflowed the destination!" );
            CR_UNLOCK_PACKER_CONTEXT(pc);
        }
	}

	if (pc->swapping)
		crPackBoundsInfoCRSWAP( bounds, payload, length, num_opcodes );
	else
		crPackBoundsInfoCR( bounds, payload, length, num_opcodes );

	pc->buffer.holds_BeginEnd |= src->holds_BeginEnd;
	pc->buffer.in_BeginEnd = src->in_BeginEnd;
	pc->buffer.holds_List |= src->holds_List;
    CR_UNLOCK_PACKER_CONTEXT(pc);
}
Esempio n. 4
0
void PACK_APIENTRY crPackBoundsInfoCR( const CRrecti *bounds, const GLbyte *payload, GLint len, GLint num_opcodes )
{
    CR_GET_PACKER_CONTEXT(pc);
    /* Don't get the buffered_ptr here because we've already 
     * verified that there's enough space for everything. */

    unsigned char *data_ptr;
    int len_aligned, total_len;

    CR_LOCK_PACKER_CONTEXT(pc);

    data_ptr = pc->buffer.data_current;
    len_aligned     = ( len + 0x3 ) & ~0x3;
    total_len = 24 + len_aligned;

    WRITE_DATA( 0, int, total_len );
    WRITE_DATA( 4, int, bounds->x1 );
    WRITE_DATA( 8, int, bounds->y1 );
    WRITE_DATA( 12, int, bounds->x2 );
    WRITE_DATA( 16, int, bounds->y2 );
    WRITE_DATA( 20, int, num_opcodes );

    /* skip the BOUNDSINFO */
    data_ptr += 24;

    /* put in padding opcodes (deliberately bogus) */
    switch ( len_aligned - len )
    {
      case 3: *data_ptr++ = 0xff; /* FALLTHROUGH */
      case 2: *data_ptr++ = 0xff; /* FALLTHROUGH */
      case 1: *data_ptr++ = 0xff; /* FALLTHROUGH */
      default: break;
    }

    crMemcpy( data_ptr, payload, len );

    WRITE_OPCODE( pc, CR_BOUNDSINFOCR_OPCODE );
    pc->buffer.data_current += 24 + len_aligned;
    CR_UNLOCK_PACKER_CONTEXT(pc);
}
Esempio n. 5
0
/*
 * Allocate space for a command that might be very large, such as
 * glTexImage2D or glBufferDataARB call.
 * The command buffer _MUST_ then be transmitted by calling crHugePacket.
 */
void *crPackAlloc( unsigned int size )
{
	CR_GET_PACKER_CONTEXT(pc);
	unsigned char *data_ptr;

	/* include space for the length and make the payload word-aligned */
	size = ( size + sizeof(unsigned int) + 0x3 ) & ~0x3;

    CR_LOCK_PACKER_CONTEXT(pc);

	if ( crPackCanHoldOpcode( pc, 1, size ) )
	{
		/* we can just put it in the current buffer */
		CR_GET_BUFFERED_POINTER_NOLOCK(pc, size );  /* NOTE: this sets data_ptr */
	}
	else 
	{
		/* Okay, it didn't fit.  Maybe it will after we flush. */
		CR_UNLOCK_PACKER_CONTEXT(pc);
		pc->Flush( pc->flush_arg );
		CR_LOCK_PACKER_CONTEXT(pc);
		if ( crPackCanHoldOpcode( pc, 1, size ) )
		{
			CR_GET_BUFFERED_POINTER_NOLOCK(pc, size );  /* NOTE: this sets data_ptr */
		}
		else
		{
			/* It's really way too big, so allocate a temporary packet
			 * with space for the single opcode plus the payload &
			 * header.
			 */
			data_ptr = (unsigned char *) 
				crAlloc( sizeof(CRMessageOpcodes) + 4 + size );

			/* skip the header & opcode space */
			data_ptr += sizeof(CRMessageOpcodes) + 4;
		}
	}

	/* At the top of the function, we added four to the request size and
	 * rounded it up to the next multiple of four.
	 *
	 * At this point, we have:
	 *
	 * HIGH MEM        | byte size - 1    |  \
	 *                   ...                  |
	 *                   ...                  | - original 'size' bytes for data
	 *                 | operand data     |   |
	 * return value -> | operand data     |  /
	 *                 | byte 3           |  \
	 *                 | byte 2           |   |- These bytes will store 'size'
	 *                 | byte 1           |   |  
	 * data_ptr ->     | byte 0           |  /
	 *                 | CR opcode        |  <- Set in packspuHuge()
	 *                 | unused           |
	 *                 | unused           |
	 *                 | unused           |
	 *                 | CRMessageOpcodes |
	 *                 | CRMessageOpcodes |
	 *                   ...               
	 *                 | CRMessageOpcodes |
	 *                 | CRMessageOpcodes |
	 * LOW MEM         +------------------+
	 */

	if (pc->swapping)
	{
		*((unsigned int *) data_ptr) = SWAP32(size);
		crDebug( "Just swapped the length, putting %d on the wire!", *((unsigned int *) data_ptr));
	}
	else
	{
		*((unsigned int *) data_ptr) = size;
	}
#ifndef CHROMIUM_THREADSAFE
	sanityCheckPointer = data_ptr + 4;
#endif
	return data_ptr + 4;
}
Esempio n. 6
0
/*
 * This is called from either the Pack SPU and the packer library whenever
 * we need to send a data buffer to the server.
 */
void packspuFlush(void *arg )
{
    ThreadInfo *thread = (ThreadInfo *) arg;
    ContextInfo *ctx;
    unsigned int len;
    CRMessageOpcodes *hdr;
    CRPackBuffer *buf;

    /* we should _always_ pass a valid <arg> value */
    CRASSERT(thread && thread->inUse);
#ifdef CHROMIUM_THREADSAFE
    CR_LOCK_PACKER_CONTEXT(thread->packer);
#endif
    ctx = thread->currentContext;
    buf = &(thread->buffer);
    CRASSERT(buf);

    /* We're done packing into the current buffer, unbind it */
    crPackReleaseBuffer( thread->packer );

    /*
    printf("%s thread=%p thread->id = %d thread->pc=%p t2->id=%d t2->pc=%p packbuf=%p packbuf=%p\n",
           __FUNCTION__, (void*) thread, (int) thread->id, thread->packer,
           (int) t2->id, t2->packer,
           buf->pack, thread->packer->buffer.pack);
    */

    if ( buf->opcode_current == buf->opcode_start ) {
        /*
        printf("%s early return\n", __FUNCTION__);
        */
        /* XXX these calls seem to help, but might be appropriate */
        crPackSetBuffer( thread->packer, buf );
        crPackResetPointers(thread->packer);
#ifdef CHROMIUM_THREADSAFE
        CR_UNLOCK_PACKER_CONTEXT(thread->packer);
#endif
        return;
    }

    hdr = __prependHeader( buf, &len, 0 );

    CRASSERT( thread->netServer.conn );

    if ( buf->holds_BeginEnd )
    {
        /*crDebug("crNetBarf %d, (%d)", len, buf->size);*/
        crNetBarf( thread->netServer.conn, &(buf->pack), hdr, len );
    }
    else
    {
        /*crDebug("crNetSend %d, (%d)", len, buf->size);*/
        crNetSend( thread->netServer.conn, &(buf->pack), hdr, len );
    }

    buf->pack = crNetAlloc( thread->netServer.conn );

    /* The network may have found a new mtu */
    buf->mtu = thread->netServer.conn->mtu;

    crPackSetBuffer( thread->packer, buf );

    crPackResetPointers(thread->packer);

#ifdef CHROMIUM_THREADSAFE
    CR_UNLOCK_PACKER_CONTEXT(thread->packer);
#endif
}
Esempio n. 7
0
void PACKSPU_APIENTRY packspu_VBoxDetachThread()
{
    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();
}