pack_buffer.c revision a08ba954dfbb6b906afd3079f7830ff920006bff
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/* Copyright (c) 2001, Stanford University
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * All rights reserved
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * See the file LICENSE.txt for information on redistributing this software.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include "cr_mem.h"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include "cr_string.h"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include "packer.h"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include "cr_error.h"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include "cr_protocol.h"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#ifndef IN_RING0
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include "cr_unpack.h"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#endif
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#ifndef IN_RING0
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncvoid crWriteUnalignedDouble( void *buffer, double d )
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync unsigned int *ui = (unsigned int *) buffer;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ui[0] = ((unsigned int *) &d)[0];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ui[1] = ((unsigned int *) &d)[1];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncvoid crWriteSwappedDouble( void *buffer, double d )
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync unsigned int *ui = (unsigned int *) buffer;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ui[0] = SWAP32(((unsigned int *) &d)[1]);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ui[1] = SWAP32(((unsigned int *) &d)[0]);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsyncdouble crReadUnalignedDouble( const void *buffer )
400422edee24dcbb377417b13ed03412cc3a226bvboxsync{
400422edee24dcbb377417b13ed03412cc3a226bvboxsync const unsigned int *ui = (unsigned int *) buffer;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync double d;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ((unsigned int *) &d)[0] = ui[0];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ((unsigned int *) &d)[1] = ui[1];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return d;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#endif
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * We need the packer to run as efficiently as possible. To avoid one
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * pointer dereference from the CRPackContext to the current CRPackBuffer,
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * we keep a _copy_ of the current CRPackBuffer in the CRPackContext and
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * operate on the fields in CRPackContext, rather than the CRPackBuffer.
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * To keep things in sync, when we change a context's
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * buffer, we have to use the crPackSet/GetBuffer() functions.
400422edee24dcbb377417b13ed03412cc3a226bvboxsync */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsyncvoid crPackSetBuffer( CRPackContext *pc, CRPackBuffer *buffer )
400422edee24dcbb377417b13ed03412cc3a226bvboxsync{
400422edee24dcbb377417b13ed03412cc3a226bvboxsync CRASSERT( pc );
400422edee24dcbb377417b13ed03412cc3a226bvboxsync CRASSERT( buffer );
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsync if (pc->currentBuffer == buffer)
400422edee24dcbb377417b13ed03412cc3a226bvboxsync return; /* re-bind is no-op */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pc->currentBuffer) {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Another buffer currently bound to this packer (shouldn't normally occur)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Release it. Fixes Ensight issue.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync crPackReleaseBuffer(pc);
400422edee24dcbb377417b13ed03412cc3a226bvboxsync }
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsync CRASSERT( pc->currentBuffer == NULL); /* release if NULL? */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync CRASSERT( buffer->context == NULL );
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsync /* bind context to buffer */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync pc->currentBuffer = buffer;
400422edee24dcbb377417b13ed03412cc3a226bvboxsync buffer->context = pc;
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsync /* update the context's packing fields with those from the buffer */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync pc->buffer = *buffer; /* struct copy */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync}
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsync#ifndef IN_RING0
400422edee24dcbb377417b13ed03412cc3a226bvboxsync/* This is useful for debugging packer problems */
400422edee24dcbb377417b13ed03412cc3a226bvboxsyncvoid crPackSetBufferDEBUG( const char *file, int line,
400422edee24dcbb377417b13ed03412cc3a226bvboxsync CRPackContext *pc, CRPackBuffer *buffer)
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsync{
400422edee24dcbb377417b13ed03412cc3a226bvboxsync crPackSetBuffer( pc, buffer );
400422edee24dcbb377417b13ed03412cc3a226bvboxsync /* record debugging info */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync pc->file = crStrdup(file);
400422edee24dcbb377417b13ed03412cc3a226bvboxsync pc->line = line;
400422edee24dcbb377417b13ed03412cc3a226bvboxsync}
400422edee24dcbb377417b13ed03412cc3a226bvboxsync#endif
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsync/*
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * Release the buffer currently attached to the context.
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * Update/resync data structures.
400422edee24dcbb377417b13ed03412cc3a226bvboxsync */
400422edee24dcbb377417b13ed03412cc3a226bvboxsyncvoid crPackReleaseBuffer( CRPackContext *pc )
400422edee24dcbb377417b13ed03412cc3a226bvboxsync{
400422edee24dcbb377417b13ed03412cc3a226bvboxsync CRPackBuffer *buf;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync CRASSERT( pc );
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync if (!pc->currentBuffer) {
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync crWarning("crPackReleaseBuffer called with no current buffer");
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync return; /* nothing to do */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync }
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync CRASSERT( pc->currentBuffer->context == pc );
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync /* buffer to release */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf = pc->currentBuffer;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync /* copy context's fields back into the buffer to update it */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync *buf = pc->buffer; /* struct copy */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsync /* unbind buffer from context */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync buf->context = NULL;
400422edee24dcbb377417b13ed03412cc3a226bvboxsync pc->currentBuffer = NULL;
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync /* zero-out context's packing fields just to be safe */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync crMemZero(&(pc->buffer), sizeof(pc->buffer));
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsync /* update the debugging fields */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync if (pc->file)
400422edee24dcbb377417b13ed03412cc3a226bvboxsync crFree(pc->file);
400422edee24dcbb377417b13ed03412cc3a226bvboxsync pc->file = NULL;
400422edee24dcbb377417b13ed03412cc3a226bvboxsync pc->line = -1;
400422edee24dcbb377417b13ed03412cc3a226bvboxsync}
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsyncvoid crPackFlushFunc( CRPackContext *pc, CRPackFlushFunc ff )
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync{
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync pc->Flush = ff;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync}
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsyncvoid crPackFlushArg( CRPackContext *pc, void *flush_arg )
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync{
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync pc->flush_arg = flush_arg;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync}
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsyncvoid crPackSendHugeFunc( CRPackContext *pc, CRPackSendHugeFunc shf )
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync{
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync pc->SendHuge = shf;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync}
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync/*
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * This basically resets the buffer attached to <pc> to the default, empty
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * state.
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsyncvoid crPackResetPointers( CRPackContext *pc )
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync{
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync const GLboolean geom_only = pc->buffer.geometry_only; /* save this flag */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync const GLboolean holds_BeginEnd = pc->buffer.holds_BeginEnd;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync const GLboolean in_BeginEnd = pc->buffer.in_BeginEnd;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync const GLboolean canBarf = pc->buffer.canBarf;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync CRPackBuffer *buf = pc->currentBuffer;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync CRASSERT(buf);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync crPackInitBuffer( buf, buf->pack, buf->size, buf->mtu
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync#ifdef IN_RING0
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync , 0
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync#endif
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync );
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync pc->buffer.geometry_only = geom_only; /* restore the flag */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync pc->buffer.holds_BeginEnd = holds_BeginEnd;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync pc->buffer.in_BeginEnd = in_BeginEnd;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync pc->buffer.canBarf = canBarf;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync}
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync/**
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * Return max number of opcodes that'll fit in the given buffer size.
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * Each opcode has at least a 1-word payload, so opcodes can occupy at most
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * 20% of the space.
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsyncint
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsynccrPackMaxOpcodes( int buffer_size )
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync{
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync int n = ( buffer_size - sizeof(CRMessageOpcodes) ) / 5;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync /* Don't forget to add one here in case the buffer size is not
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * divisible by 4. Thanks to Ken Moreland for finding this.
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync n++;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync /* round up to multiple of 4 */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync n = (n + 0x3) & (~0x3);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync return n;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync}
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync/**
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * Return max number of data bytes that'll fit in the given buffer size.
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsyncint
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsynccrPackMaxData( int buffer_size )
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync{
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync int n = buffer_size - sizeof(CRMessageOpcodes);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync n -= crPackMaxOpcodes(buffer_size);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync return n;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync}
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync/**
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * Initialize the given CRPackBuffer object.
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * The buffer may or may not be currently bound to a CRPackContext.
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync *
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * Opcodes and operands are packed into a buffer in a special way.
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * Opcodes start at opcode_start and go downward in memory while operands
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * start at data_start and go upward in memory. The buffer is full when we
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * either run out of opcode space or operand space.
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync *
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * Diagram (memory addresses increase upward):
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync *
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * data_end -> | | <- buf->pack + buf->size
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * +---------+
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * | |
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * | |
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * | operands|
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * | |
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * | |
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * data_start -> +---------+
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * opcode_start -> | |
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * | |
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * | opcodes |
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * | |
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * | |
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * opcode_end -> +---------+ <- buf->pack
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync *
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * \param buf the CRPackBuffer to initialize
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * \param pack the address of the buffer for packing opcodes/operands.
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * \param size size of the buffer, in bytes
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * \param mtu max transmission unit size, in bytes. When the buffer
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * has 'mtu' bytes in it, we have to send it. The MTU might
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * be somewhat smaller than the buffer size.
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsyncvoid crPackInitBuffer( CRPackBuffer *buf, void *pack, int size, int mtu
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync#ifdef IN_RING0
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync , unsigned int num_opcodes
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync#endif
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync )
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync{
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync#ifndef IN_RING0
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync unsigned int num_opcodes;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync#endif
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync CRASSERT(mtu <= size);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf->size = size;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf->mtu = mtu;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf->pack = pack;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync#ifdef IN_RING0
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync if(!num_opcodes)
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync#endif
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync {
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync num_opcodes = crPackMaxOpcodes( buf->size );
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync }
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf->data_start =
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync (unsigned char *) buf->pack + num_opcodes + sizeof(CRMessageOpcodes);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf->data_current = buf->data_start;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf->data_end = (unsigned char *) buf->pack + buf->size;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf->opcode_start = buf->data_start - 1;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf->opcode_current = buf->opcode_start;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf->opcode_end = buf->opcode_start - num_opcodes;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf->geometry_only = GL_FALSE;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf->holds_BeginEnd = GL_FALSE;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf->in_BeginEnd = GL_FALSE;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync buf->canBarf = GL_FALSE;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync if (buf->context) {
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync /* Also reset context's packing fields */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync CRPackContext *pc = buf->context;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync CRASSERT(pc->currentBuffer == buf);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync /*crMemcpy( &(pc->buffer), buf, sizeof(*buf) );*/
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync pc->buffer = *buf;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync }
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync}
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsyncint crPackCanHoldBuffer( CR_PACKER_CONTEXT_ARGDECL const CRPackBuffer *src )
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync{
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync const int num_data = crPackNumData(src);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync const int num_opcode = crPackNumOpcodes(src);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync int res;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync CR_GET_PACKER_CONTEXT(pc);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync CR_LOCK_PACKER_CONTEXT(pc);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync res = crPackCanHoldOpcode( pc, num_opcode, num_data );
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync CR_UNLOCK_PACKER_CONTEXT(pc);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync return res;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync}
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsyncint crPackCanHoldBoundedBuffer( CR_PACKER_CONTEXT_ARGDECL const CRPackBuffer *src )
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync{
400422edee24dcbb377417b13ed03412cc3a226bvboxsync const int len_aligned = (src->data_current - src->opcode_current - 1 + 3) & ~3;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync CR_GET_PACKER_CONTEXT(pc);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync /* 24 is the size of the bounds-info packet... */
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync return crPackCanHoldOpcode( pc, 1, len_aligned + 24 );
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync}
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsyncvoid crPackAppendBuffer( CR_PACKER_CONTEXT_ARGDECL const CRPackBuffer *src )
400422edee24dcbb377417b13ed03412cc3a226bvboxsync{
400422edee24dcbb377417b13ed03412cc3a226bvboxsync CR_GET_PACKER_CONTEXT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync const int num_data = crPackNumData(src);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync const int num_opcode = crPackNumOpcodes(src);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CRASSERT(num_data >= 0);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CRASSERT(num_opcode >= 0);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_LOCK_PACKER_CONTEXT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* don't append onto ourself! */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CRASSERT(pc->currentBuffer);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CRASSERT(pc->currentBuffer != src);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (!crPackCanHoldBuffer(CR_PACKER_CONTEXT_ARG src))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (src->holds_BeginEnd)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync crWarning( "crPackAppendBuffer: overflowed the destination!" );
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_UNLOCK_PACKER_CONTEXT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync crError( "crPackAppendBuffer: overflowed the destination!" );
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_UNLOCK_PACKER_CONTEXT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Copy the buffer data/operands which are at the head of the buffer */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync crMemcpy( pc->buffer.data_current, src->data_start, num_data );
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pc->buffer.data_current += num_data;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Copy the buffer opcodes which are at the tail of the buffer */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CRASSERT( pc->buffer.opcode_current - num_opcode >= pc->buffer.opcode_end );
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync crMemcpy( pc->buffer.opcode_current + 1 - num_opcode, src->opcode_current + 1,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync num_opcode );
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pc->buffer.opcode_current -= num_opcode;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pc->buffer.holds_BeginEnd |= src->holds_BeginEnd;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pc->buffer.in_BeginEnd = src->in_BeginEnd;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pc->buffer.holds_List |= src->holds_List;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_UNLOCK_PACKER_CONTEXT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncvoid
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsynccrPackAppendBoundedBuffer( CR_PACKER_CONTEXT_ARGDECL const CRPackBuffer *src, const CRrecti *bounds )
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_GET_PACKER_CONTEXT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync const GLbyte *payload = (const GLbyte *) src->opcode_current + 1;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync const int num_opcodes = crPackNumOpcodes(src);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync const int length = src->data_current - src->opcode_current - 1;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CRASSERT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_LOCK_PACKER_CONTEXT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CRASSERT(pc->currentBuffer);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CRASSERT(pc->currentBuffer != src);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * payload points to the block of opcodes immediately followed by operands.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( !crPackCanHoldBoundedBuffer( CR_PACKER_CONTEXT_ARG src ) )
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (src->holds_BeginEnd)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync crWarning( "crPackAppendBoundedBuffer: overflowed the destination!" );
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_UNLOCK_PACKER_CONTEXT(pc);
400422edee24dcbb377417b13ed03412cc3a226bvboxsync return;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
400422edee24dcbb377417b13ed03412cc3a226bvboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
400422edee24dcbb377417b13ed03412cc3a226bvboxsync crError( "crPackAppendBoundedBuffer: overflowed the destination!" );
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_UNLOCK_PACKER_CONTEXT(pc);
400422edee24dcbb377417b13ed03412cc3a226bvboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync if (pc->swapping)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync crPackBoundsInfoCRSWAP( CR_PACKER_CONTEXT_ARG bounds, payload, length, num_opcodes );
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync else
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync crPackBoundsInfoCR( CR_PACKER_CONTEXT_ARG bounds, payload, length, num_opcodes );
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync pc->buffer.holds_BeginEnd |= src->holds_BeginEnd;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync pc->buffer.in_BeginEnd = src->in_BeginEnd;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync pc->buffer.holds_List |= src->holds_List;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync CR_UNLOCK_PACKER_CONTEXT(pc);
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync}
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync#ifndef CHROMIUM_THREADSAFE
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsyncstatic unsigned char *sanityCheckPointer = NULL;
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync#endif
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync/*
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * Allocate space for a command that might be very large, such as
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync * glTexImage2D or glBufferDataARB call.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * The command buffer _MUST_ then be transmitted by calling crHugePacket.
972c3ecf2c929440ce70e51af38ba021101c8f7bvboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncvoid *crPackAlloc( CR_PACKER_CONTEXT_ARGDECL unsigned int size )
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_GET_PACKER_CONTEXT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync unsigned char *data_ptr;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* include space for the length and make the payload word-aligned */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync size = ( size + sizeof(unsigned int) + 0x3 ) & ~0x3;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_LOCK_PACKER_CONTEXT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( crPackCanHoldOpcode( pc, 1, size ) )
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* we can just put it in the current buffer */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_GET_BUFFERED_POINTER_NOLOCK(pc, size ); /* NOTE: this sets data_ptr */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
400422edee24dcbb377417b13ed03412cc3a226bvboxsync {
400422edee24dcbb377417b13ed03412cc3a226bvboxsync /* Okay, it didn't fit. Maybe it will after we flush. */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync CR_UNLOCK_PACKER_CONTEXT(pc);
400422edee24dcbb377417b13ed03412cc3a226bvboxsync pc->Flush( pc->flush_arg );
400422edee24dcbb377417b13ed03412cc3a226bvboxsync CR_LOCK_PACKER_CONTEXT(pc);
400422edee24dcbb377417b13ed03412cc3a226bvboxsync if ( crPackCanHoldOpcode( pc, 1, size ) )
400422edee24dcbb377417b13ed03412cc3a226bvboxsync {
400422edee24dcbb377417b13ed03412cc3a226bvboxsync CR_GET_BUFFERED_POINTER_NOLOCK(pc, size ); /* NOTE: this sets data_ptr */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync }
400422edee24dcbb377417b13ed03412cc3a226bvboxsync else
400422edee24dcbb377417b13ed03412cc3a226bvboxsync {
400422edee24dcbb377417b13ed03412cc3a226bvboxsync /* It's really way too big, so allocate a temporary packet
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * with space for the single opcode plus the payload &
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * header.
400422edee24dcbb377417b13ed03412cc3a226bvboxsync */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync data_ptr = (unsigned char *)
400422edee24dcbb377417b13ed03412cc3a226bvboxsync crAlloc( sizeof(CRMessageOpcodes) + 4 + size );
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsync /* skip the header & opcode space */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync data_ptr += sizeof(CRMessageOpcodes) + 4;
400422edee24dcbb377417b13ed03412cc3a226bvboxsync }
400422edee24dcbb377417b13ed03412cc3a226bvboxsync }
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsync /* At the top of the function, we added four to the request size and
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * rounded it up to the next multiple of four.
400422edee24dcbb377417b13ed03412cc3a226bvboxsync *
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * At this point, we have:
400422edee24dcbb377417b13ed03412cc3a226bvboxsync *
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * HIGH MEM | byte size - 1 | \
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * ... |
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * ... | - original 'size' bytes for data
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * | operand data | |
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * return value -> | operand data | /
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * | byte 3 | \
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * | byte 2 | |- These bytes will store 'size'
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * | byte 1 | |
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * data_ptr -> | byte 0 | /
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * | CR opcode | <- Set in packspuHuge()
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * | unused |
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * | unused |
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * | unused |
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * | CRMessageOpcodes |
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * | CRMessageOpcodes |
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * ...
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * | CRMessageOpcodes |
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * | CRMessageOpcodes |
400422edee24dcbb377417b13ed03412cc3a226bvboxsync * LOW MEM +------------------+
400422edee24dcbb377417b13ed03412cc3a226bvboxsync */
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
400422edee24dcbb377417b13ed03412cc3a226bvboxsync if (pc->swapping)
400422edee24dcbb377417b13ed03412cc3a226bvboxsync {
400422edee24dcbb377417b13ed03412cc3a226bvboxsync *((unsigned int *) data_ptr) = SWAP32(size);
400422edee24dcbb377417b13ed03412cc3a226bvboxsync crDebug( "Just swapped the length, putting %d on the wire!", *((unsigned int *) data_ptr));
400422edee24dcbb377417b13ed03412cc3a226bvboxsync }
400422edee24dcbb377417b13ed03412cc3a226bvboxsync else
400422edee24dcbb377417b13ed03412cc3a226bvboxsync {
400422edee24dcbb377417b13ed03412cc3a226bvboxsync *((unsigned int *) data_ptr) = size;
400422edee24dcbb377417b13ed03412cc3a226bvboxsync }
400422edee24dcbb377417b13ed03412cc3a226bvboxsync#ifndef CHROMIUM_THREADSAFE
400422edee24dcbb377417b13ed03412cc3a226bvboxsync sanityCheckPointer = data_ptr + 4;
400422edee24dcbb377417b13ed03412cc3a226bvboxsync#endif
400422edee24dcbb377417b13ed03412cc3a226bvboxsync return data_ptr + 4;
400422edee24dcbb377417b13ed03412cc3a226bvboxsync}
400422edee24dcbb377417b13ed03412cc3a226bvboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#define IS_BUFFERED( packet ) \
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ((unsigned char *) (packet) >= pc->buffer.data_start && \
400422edee24dcbb377417b13ed03412cc3a226bvboxsync (unsigned char *) (packet) < pc->buffer.data_end)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Transmit a packet which was allocated with crPackAlloc.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncvoid crHugePacket( CR_PACKER_CONTEXT_ARGDECL CROpcode opcode, void *packet )
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_GET_PACKER_CONTEXT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#ifndef CHROMIUM_THREADSAFE
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CRASSERT(sanityCheckPointer == packet);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync sanityCheckPointer = NULL;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#endif
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( IS_BUFFERED( packet ) )
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync WRITE_OPCODE( pc, opcode );
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pc->SendHuge( opcode, packet );
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncvoid crPackFree( CR_PACKER_CONTEXT_ARGDECL void *packet )
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_GET_PACKER_CONTEXT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( IS_BUFFERED( packet ) )
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_UNLOCK_PACKER_CONTEXT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CR_UNLOCK_PACKER_CONTEXT(pc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* the pointer passed in doesn't include the space for the single
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * opcode (4 bytes because of the alignment requirement) or the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * length field or the header */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync crFree( (unsigned char *) packet - 8 - sizeof(CRMessageOpcodes) );
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncvoid crNetworkPointerWrite( CRNetworkPointer *dst, void *src )
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* init CRNetworkPointer with invalid values */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync dst->ptrAlign[0] = 0xDeadBeef;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync dst->ptrAlign[1] = 0xCafeBabe;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* copy the pointer's value into the CRNetworkPointer */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync crMemcpy( dst, &src, sizeof(src) );
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* if either assertion fails, it probably means that a packer function
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * (which returns a value) was called without setting up the writeback
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * pointer, or something like that.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CRASSERT(dst->ptrAlign[0] != 0xffffffff);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync CRASSERT(dst->ptrAlign[0] != 0xDeadBeef);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync