summaryrefslogtreecommitdiffstats
path: root/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Additions/common/crOpenGL/pack/packspu_net.c')
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_net.c284
1 files changed, 284 insertions, 0 deletions
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c
new file mode 100644
index 00000000..6d5d41d6
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c
@@ -0,0 +1,284 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_pack.h"
+#include "cr_mem.h"
+#include "cr_net.h"
+#include "cr_pixeldata.h"
+#include "cr_protocol.h"
+#include "cr_error.h"
+#include "packspu.h"
+#include "packspu_proto.h"
+
+uint32_t g_u32VBoxHostCaps = 0;
+
+static void
+packspuWriteback( const CRMessageWriteback *wb )
+{
+ int *writeback;
+ crMemcpy( &writeback, &(wb->writeback_ptr), sizeof( writeback ) );
+ *writeback = 0;
+}
+
+/**
+ * XXX Note that this routine is identical to crNetRecvReadback except
+ * we set *writeback=0 instead of decrementing it. Hmmm.
+ */
+static void
+packspuReadback( const CRMessageReadback *rb, unsigned int len )
+{
+ /* minus the header, the destination pointer,
+ * *and* the implicit writeback pointer at the head. */
+
+ int payload_len = len - sizeof( *rb );
+ int *writeback;
+ void *dest_ptr;
+ crMemcpy( &writeback, &(rb->writeback_ptr), sizeof( writeback ) );
+ crMemcpy( &dest_ptr, &(rb->readback_ptr), sizeof( dest_ptr ) );
+
+ *writeback = 0;
+ crMemcpy( dest_ptr, ((char *)rb) + sizeof(*rb), payload_len );
+}
+
+static void
+packspuReadPixels( const CRMessageReadPixels *rp, unsigned int len )
+{
+ crNetRecvReadPixels( rp, len );
+ --pack_spu.ReadPixels;
+}
+
+static int
+packspuReceiveData( CRConnection *conn, CRMessage *msg, unsigned int len )
+{
+ RT_NOREF(conn);
+ if (msg->header.type == CR_MESSAGE_REDIR_PTR)
+ msg = (CRMessage*) msg->redirptr.pMessage;
+
+ switch( msg->header.type )
+ {
+ case CR_MESSAGE_READ_PIXELS:
+ packspuReadPixels( &(msg->readPixels), len );
+ break;
+ case CR_MESSAGE_WRITEBACK:
+ packspuWriteback( &(msg->writeback) );
+ break;
+ case CR_MESSAGE_READBACK:
+ packspuReadback( &(msg->readback), len );
+ break;
+ default:
+ /*crWarning( "Why is the pack SPU getting a message of type 0x%x?", msg->type ); */
+ return 0; /* NOT HANDLED */
+ }
+ return 1; /* HANDLED */
+}
+
+static CRMessageOpcodes *
+__prependHeader( CRPackBuffer *buf, unsigned int *len, unsigned int senderID )
+{
+ int num_opcodes;
+ CRMessageOpcodes *hdr;
+ RT_NOREF(senderID);
+
+ CRASSERT( buf );
+ CRASSERT( buf->opcode_current < buf->opcode_start );
+ CRASSERT( buf->opcode_current >= buf->opcode_end );
+ CRASSERT( buf->data_current > buf->data_start );
+ CRASSERT( buf->data_current <= buf->data_end );
+
+ num_opcodes = buf->opcode_start - buf->opcode_current;
+ hdr = (CRMessageOpcodes *)
+ ( buf->data_start - ( ( num_opcodes + 3 ) & ~0x3 ) - sizeof(*hdr) );
+
+ CRASSERT( (void *) hdr >= buf->pack );
+
+ if (pack_spu.swap)
+ {
+ hdr->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
+ hdr->numOpcodes = SWAP32(num_opcodes);
+ }
+ else
+ {
+ hdr->header.type = CR_MESSAGE_OPCODES;
+ hdr->numOpcodes = num_opcodes;
+ }
+
+ *len = buf->data_current - (unsigned char *) hdr;
+
+ return hdr;
+}
+
+
+/*
+ * 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);
+
+ if (ctx && ctx->fCheckZerroVertAttr)
+ crStateCurrentRecoverNew(ctx->clientState, &thread->packer->current);
+
+ /* 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
+}
+
+
+/**
+ * XXX NOTE: there's a lot of duplicate code here common to the
+ * pack, tilesort and replicate SPUs. Try to simplify someday!
+ */
+void packspuHuge( CROpcode opcode, void *buf )
+{
+ GET_THREAD(thread);
+ unsigned int len;
+ unsigned char *src;
+ CRMessageOpcodes *msg;
+
+ CRASSERT(thread);
+
+ /* packet length is indicated by the variable length field, and
+ includes an additional word for the opcode (with alignment) and
+ a header */
+ len = ((unsigned int *) buf)[-1];
+ if (pack_spu.swap)
+ {
+ /* It's already been swapped, swap it back. */
+ len = SWAP32(len);
+ }
+ len += 4 + sizeof(CRMessageOpcodes);
+
+ /* write the opcode in just before the length */
+ ((unsigned char *) buf)[-5] = (unsigned char) opcode;
+
+ /* fix up the pointer to the packet to include the length & opcode
+ & header */
+ src = (unsigned char *) buf - 8 - sizeof(CRMessageOpcodes);
+
+ msg = (CRMessageOpcodes *) src;
+
+ if (pack_spu.swap)
+ {
+ msg->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
+ msg->numOpcodes = SWAP32(1);
+ }
+ else
+ {
+ msg->header.type = CR_MESSAGE_OPCODES;
+ msg->numOpcodes = 1;
+ }
+
+ CRASSERT( thread->netServer.conn );
+ crNetSend( thread->netServer.conn, NULL, src, len );
+}
+
+static void packspuFirstConnectToServer( CRNetServer *server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , struct VBOXUHGSMI *pHgsmi
+#endif
+ )
+{
+ crNetInit( packspuReceiveData, NULL );
+ crNetServerConnect( server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ if (server->conn)
+ {
+ g_u32VBoxHostCaps = crNetHostCapsGet();
+ crPackCapsSet(g_u32VBoxHostCaps);
+ }
+}
+
+void packspuConnectToServer( CRNetServer *server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , struct VBOXUHGSMI *pHgsmi
+#endif
+ )
+{
+ if (pack_spu.numThreads == 0) {
+ packspuFirstConnectToServer( server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ if (!server->conn) {
+ crError("packspuConnectToServer: no connection on first create!");
+ return;
+ }
+ pack_spu.swap = server->conn->swap;
+ }
+ else {
+ /* a new pthread */
+ crNetNewClient(server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ }
+}