VirtualBox

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

Last change on this file since 52451 was 52451, checked in by vboxsync, 10 years ago

crOpenGL: command blocks flushing

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.6 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
16uint32_t g_u32VBoxHostCaps = 0;
17
18static void
19packspuWriteback( const CRMessageWriteback *wb )
20{
21 int *writeback;
22 crMemcpy( &writeback, &(wb->writeback_ptr), sizeof( writeback ) );
23 *writeback = 0;
24}
25
26/**
27 * XXX Note that this routine is identical to crNetRecvReadback except
28 * we set *writeback=0 instead of decrementing it. Hmmm.
29 */
30static void
31packspuReadback( const CRMessageReadback *rb, unsigned int len )
32{
33 /* minus the header, the destination pointer,
34 * *and* the implicit writeback pointer at the head. */
35
36 int payload_len = len - sizeof( *rb );
37 int *writeback;
38 void *dest_ptr;
39 crMemcpy( &writeback, &(rb->writeback_ptr), sizeof( writeback ) );
40 crMemcpy( &dest_ptr, &(rb->readback_ptr), sizeof( dest_ptr ) );
41
42 *writeback = 0;
43 crMemcpy( dest_ptr, ((char *)rb) + sizeof(*rb), payload_len );
44}
45
46static void
47packspuReadPixels( const CRMessageReadPixels *rp, unsigned int len )
48{
49 crNetRecvReadPixels( rp, len );
50 --pack_spu.ReadPixels;
51}
52
53static int
54packspuReceiveData( CRConnection *conn, CRMessage *msg, unsigned int len )
55{
56 if (msg->header.type == CR_MESSAGE_REDIR_PTR)
57 msg = (CRMessage*) msg->redirptr.pMessage;
58
59 switch( msg->header.type )
60 {
61 case CR_MESSAGE_READ_PIXELS:
62 packspuReadPixels( &(msg->readPixels), len );
63 break;
64 case CR_MESSAGE_WRITEBACK:
65 packspuWriteback( &(msg->writeback) );
66 break;
67 case CR_MESSAGE_READBACK:
68 packspuReadback( &(msg->readback), len );
69 break;
70 default:
71 /*crWarning( "Why is the pack SPU getting a message of type 0x%x?", msg->type ); */
72 return 0; /* NOT HANDLED */
73 }
74 return 1; /* HANDLED */
75}
76
77static CRMessageOpcodes *
78__prependHeader( CRPackBuffer *buf, unsigned int *len, unsigned int senderID )
79{
80 int num_opcodes;
81 CRMessageOpcodes *hdr;
82
83 CRASSERT( buf );
84 CRASSERT( buf->opcode_current < buf->opcode_start );
85 CRASSERT( buf->opcode_current >= buf->opcode_end );
86 CRASSERT( buf->data_current > buf->data_start );
87 CRASSERT( buf->data_current <= buf->data_end );
88
89 num_opcodes = buf->opcode_start - buf->opcode_current;
90 hdr = (CRMessageOpcodes *)
91 ( buf->data_start - ( ( num_opcodes + 3 ) & ~0x3 ) - sizeof(*hdr) );
92
93 CRASSERT( (void *) hdr >= buf->pack );
94
95 if (pack_spu.swap)
96 {
97 hdr->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
98 hdr->numOpcodes = SWAP32(num_opcodes);
99 }
100 else
101 {
102 hdr->header.type = CR_MESSAGE_OPCODES;
103 hdr->numOpcodes = num_opcodes;
104 }
105
106 *len = buf->data_current - (unsigned char *) hdr;
107
108 return hdr;
109}
110
111
112/*
113 * This is called from either the Pack SPU and the packer library whenever
114 * we need to send a data buffer to the server.
115 */
116void packspuFlush(void *arg )
117{
118 ThreadInfo *thread = (ThreadInfo *) arg;
119 ContextInfo *ctx;
120 unsigned int len;
121 CRMessageOpcodes *hdr;
122 CRPackBuffer *buf;
123
124 /* we should _always_ pass a valid <arg> value */
125 CRASSERT(thread && thread->inUse);
126#ifdef CHROMIUM_THREADSAFE
127 CR_LOCK_PACKER_CONTEXT(thread->packer);
128#endif
129 ctx = thread->currentContext;
130 buf = &(thread->buffer);
131 CRASSERT(buf);
132
133 if (ctx && ctx->fCheckZerroVertAttr)
134 crStateCurrentRecoverNew(ctx->clientState, &thread->packer->current);
135
136 /* We're done packing into the current buffer, unbind it */
137 crPackReleaseBuffer( thread->packer );
138
139 /*
140 printf("%s thread=%p thread->id = %d thread->pc=%p t2->id=%d t2->pc=%p packbuf=%p packbuf=%p\n",
141 __FUNCTION__, (void*) thread, (int) thread->id, thread->packer,
142 (int) t2->id, t2->packer,
143 buf->pack, thread->packer->buffer.pack);
144 */
145
146 if ( buf->opcode_current == buf->opcode_start ) {
147 /*
148 printf("%s early return\n", __FUNCTION__);
149 */
150 /* XXX these calls seem to help, but might be appropriate */
151 crPackSetBuffer( thread->packer, buf );
152 crPackResetPointers(thread->packer);
153#ifdef CHROMIUM_THREADSAFE
154 CR_UNLOCK_PACKER_CONTEXT(thread->packer);
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#endif
186}
187
188
189/**
190 * XXX NOTE: there's a lot of duplicate code here common to the
191 * pack, tilesort and replicate SPUs. Try to simplify someday!
192 */
193void packspuHuge( CROpcode opcode, void *buf )
194{
195 GET_THREAD(thread);
196 unsigned int len;
197 unsigned char *src;
198 CRMessageOpcodes *msg;
199
200 CRASSERT(thread);
201
202 /* packet length is indicated by the variable length field, and
203 includes an additional word for the opcode (with alignment) and
204 a header */
205 len = ((unsigned int *) buf)[-1];
206 if (pack_spu.swap)
207 {
208 /* It's already been swapped, swap it back. */
209 len = SWAP32(len);
210 }
211 len += 4 + sizeof(CRMessageOpcodes);
212
213 /* write the opcode in just before the length */
214 ((unsigned char *) buf)[-5] = (unsigned char) opcode;
215
216 /* fix up the pointer to the packet to include the length & opcode
217 & header */
218 src = (unsigned char *) buf - 8 - sizeof(CRMessageOpcodes);
219
220 msg = (CRMessageOpcodes *) src;
221
222 if (pack_spu.swap)
223 {
224 msg->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
225 msg->numOpcodes = SWAP32(1);
226 }
227 else
228 {
229 msg->header.type = CR_MESSAGE_OPCODES;
230 msg->numOpcodes = 1;
231 }
232
233 CRASSERT( thread->netServer.conn );
234 crNetSend( thread->netServer.conn, NULL, src, len );
235}
236
237static void packspuFirstConnectToServer( CRNetServer *server
238#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
239 , struct VBOXUHGSMI *pHgsmi
240#endif
241 )
242{
243 crNetInit( packspuReceiveData, NULL );
244 crNetServerConnect( server
245#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
246 , pHgsmi
247#endif
248 );
249 if (server->conn)
250 {
251 g_u32VBoxHostCaps = crNetHostCapsGet();
252 crPackCapsSet(g_u32VBoxHostCaps);
253 }
254}
255
256void packspuConnectToServer( CRNetServer *server
257#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
258 , struct VBOXUHGSMI *pHgsmi
259#endif
260 )
261{
262 if (pack_spu.numThreads == 0) {
263 packspuFirstConnectToServer( server
264#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
265 , pHgsmi
266#endif
267 );
268 if (!server->conn) {
269 crError("packspuConnectToServer: no connection on first create!");
270 return;
271 }
272 pack_spu.swap = server->conn->swap;
273 }
274 else {
275 /* a new pthread */
276 crNetNewClient(server
277#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
278 , pHgsmi
279#endif
280 );
281 }
282}
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