VirtualBox

source: vbox/trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c@ 34310

Last change on this file since 34310 was 33475, checked in by vboxsync, 14 years ago

crOpenGL/wddm: multithreading fix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.5 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "cr_pack.h"
8#include "cr_mem.h"
9#include "cr_net.h"
10#include "cr_pixeldata.h"
11#include "cr_protocol.h"
12#include "cr_error.h"
13#include "packspu.h"
14#include "packspu_proto.h"
15
16static void
17packspuWriteback( const CRMessageWriteback *wb )
18{
19 int *writeback;
20 crMemcpy( &writeback, &(wb->writeback_ptr), sizeof( writeback ) );
21 *writeback = 0;
22}
23
24/**
25 * XXX Note that this routine is identical to crNetRecvReadback except
26 * we set *writeback=0 instead of decrementing it. Hmmm.
27 */
28static void
29packspuReadback( const CRMessageReadback *rb, unsigned int len )
30{
31 /* minus the header, the destination pointer,
32 * *and* the implicit writeback pointer at the head. */
33
34 int payload_len = len - sizeof( *rb );
35 int *writeback;
36 void *dest_ptr;
37 crMemcpy( &writeback, &(rb->writeback_ptr), sizeof( writeback ) );
38 crMemcpy( &dest_ptr, &(rb->readback_ptr), sizeof( dest_ptr ) );
39
40 *writeback = 0;
41 crMemcpy( dest_ptr, ((char *)rb) + sizeof(*rb), payload_len );
42}
43
44static void
45packspuReadPixels( const CRMessageReadPixels *rp, unsigned int len )
46{
47 crNetRecvReadPixels( rp, len );
48 --pack_spu.ReadPixels;
49}
50
51static int
52packspuReceiveData( CRConnection *conn, CRMessage *msg, unsigned int len )
53{
54 if (msg->header.type == CR_MESSAGE_REDIR_PTR)
55 msg = (CRMessage*) msg->redirptr.pMessage;
56
57 switch( msg->header.type )
58 {
59 case CR_MESSAGE_READ_PIXELS:
60 packspuReadPixels( &(msg->readPixels), len );
61 break;
62 case CR_MESSAGE_WRITEBACK:
63 packspuWriteback( &(msg->writeback) );
64 break;
65 case CR_MESSAGE_READBACK:
66 packspuReadback( &(msg->readback), len );
67 break;
68 default:
69 /*crWarning( "Why is the pack SPU getting a message of type 0x%x?", msg->type ); */
70 return 0; /* NOT HANDLED */
71 }
72 return 1; /* HANDLED */
73}
74
75static CRMessageOpcodes *
76__prependHeader( CRPackBuffer *buf, unsigned int *len, unsigned int senderID )
77{
78 int num_opcodes;
79 CRMessageOpcodes *hdr;
80
81 CRASSERT( buf );
82 CRASSERT( buf->opcode_current < buf->opcode_start );
83 CRASSERT( buf->opcode_current >= buf->opcode_end );
84 CRASSERT( buf->data_current > buf->data_start );
85 CRASSERT( buf->data_current <= buf->data_end );
86
87 num_opcodes = buf->opcode_start - buf->opcode_current;
88 hdr = (CRMessageOpcodes *)
89 ( buf->data_start - ( ( num_opcodes + 3 ) & ~0x3 ) - sizeof(*hdr) );
90
91 CRASSERT( (void *) hdr >= buf->pack );
92
93 if (pack_spu.swap)
94 {
95 hdr->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
96 hdr->numOpcodes = SWAP32(num_opcodes);
97 }
98 else
99 {
100 hdr->header.type = CR_MESSAGE_OPCODES;
101 hdr->numOpcodes = num_opcodes;
102 }
103
104 *len = buf->data_current - (unsigned char *) hdr;
105
106 return hdr;
107}
108
109
110/*
111 * This is called from either the Pack SPU and the packer library whenever
112 * we need to send a data buffer to the server.
113 */
114void packspuFlush(void *arg )
115{
116 ThreadInfo *thread = (ThreadInfo *) arg;
117 ContextInfo *ctx;
118 unsigned int len;
119 CRMessageOpcodes *hdr;
120 CRPackBuffer *buf;
121
122#ifdef CHROMIUM_THREADSAFE
123 crLockMutex(&_PackMutex);
124#endif
125
126 /* we should _always_ pass a valid <arg> value */
127 CRASSERT(thread);
128#ifdef CHROMIUM_THREADSAFE
129 CR_LOCK_PACKER_CONTEXT(thread->packer);
130#endif
131 ctx = thread->currentContext;
132 buf = &(thread->buffer);
133 CRASSERT(buf);
134
135 /* We're done packing into the current buffer, unbind it */
136 crPackReleaseBuffer( thread->packer );
137
138 /*
139 printf("%s thread=%p thread->id = %d thread->pc=%p t2->id=%d t2->pc=%p packbuf=%p packbuf=%p\n",
140 __FUNCTION__, (void*) thread, (int) thread->id, thread->packer,
141 (int) t2->id, t2->packer,
142 buf->pack, thread->packer->buffer.pack);
143 */
144
145 if ( buf->opcode_current == buf->opcode_start ) {
146 /*
147 printf("%s early return\n", __FUNCTION__);
148 */
149 /* XXX these calls seem to help, but might be appropriate */
150 crPackSetBuffer( thread->packer, buf );
151 crPackResetPointers(thread->packer);
152#ifdef CHROMIUM_THREADSAFE
153 CR_UNLOCK_PACKER_CONTEXT(thread->packer);
154 crUnlockMutex(&_PackMutex);
155#endif
156 return;
157 }
158
159 hdr = __prependHeader( buf, &len, 0 );
160
161 CRASSERT( thread->netServer.conn );
162
163 if ( buf->holds_BeginEnd )
164 {
165 /*crDebug("crNetBarf %d, (%d)", len, buf->size);*/
166 crNetBarf( thread->netServer.conn, &(buf->pack), hdr, len );
167 }
168 else
169 {
170 /*crDebug("crNetSend %d, (%d)", len, buf->size);*/
171 crNetSend( thread->netServer.conn, &(buf->pack), hdr, len );
172 }
173
174 buf->pack = crNetAlloc( thread->netServer.conn );
175
176 /* The network may have found a new mtu */
177 buf->mtu = thread->netServer.conn->mtu;
178
179 crPackSetBuffer( thread->packer, buf );
180
181 crPackResetPointers(thread->packer);
182
183#ifdef CHROMIUM_THREADSAFE
184 CR_UNLOCK_PACKER_CONTEXT(thread->packer);
185 crUnlockMutex(&_PackMutex);
186#endif
187}
188
189
190/**
191 * XXX NOTE: there's a lot of duplicate code here common to the
192 * pack, tilesort and replicate SPUs. Try to simplify someday!
193 */
194void packspuHuge( CROpcode opcode, void *buf )
195{
196 GET_THREAD(thread);
197 unsigned int len;
198 unsigned char *src;
199 CRMessageOpcodes *msg;
200
201 CRASSERT(thread);
202
203 /* packet length is indicated by the variable length field, and
204 includes an additional word for the opcode (with alignment) and
205 a header */
206 len = ((unsigned int *) buf)[-1];
207 if (pack_spu.swap)
208 {
209 /* It's already been swapped, swap it back. */
210 len = SWAP32(len);
211 }
212 len += 4 + sizeof(CRMessageOpcodes);
213
214 /* write the opcode in just before the length */
215 ((unsigned char *) buf)[-5] = (unsigned char) opcode;
216
217 /* fix up the pointer to the packet to include the length & opcode
218 & header */
219 src = (unsigned char *) buf - 8 - sizeof(CRMessageOpcodes);
220
221 msg = (CRMessageOpcodes *) src;
222
223 if (pack_spu.swap)
224 {
225 msg->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
226 msg->numOpcodes = SWAP32(1);
227 }
228 else
229 {
230 msg->header.type = CR_MESSAGE_OPCODES;
231 msg->numOpcodes = 1;
232 }
233
234 CRASSERT( thread->netServer.conn );
235 crNetSend( thread->netServer.conn, NULL, src, len );
236}
237
238void packspuConnectToServer( CRNetServer *server )
239{
240 crNetInit( packspuReceiveData, NULL );
241 crNetServerConnect( server );
242}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette