VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h@ 45066

Last change on this file since 45066 was 45066, checked in by vboxsync, 12 years ago

crOpenGL: misc bugfixes & cleanups

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 15.0 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#ifndef INCLUDE_CR_SERVER_H
8#define INCLUDE_CR_SERVER_H
9
10#include "cr_spu.h"
11#include "cr_net.h"
12#include "cr_hash.h"
13#include "cr_protocol.h"
14#include "cr_glstate.h"
15#include "cr_vreg.h"
16#include "spu_dispatch_table.h"
17
18#include "state/cr_currentpointers.h"
19
20#include <iprt/types.h>
21#include <iprt/err.h>
22#include <iprt/string.h>
23
24#include <VBox/vmm/ssm.h>
25
26#ifdef VBOX_WITH_CRHGSMI
27# include <VBox/VBoxVideo.h>
28#endif
29#include <VBox/Hardware/VBoxVideoVBE.h>
30
31#include "cr_vreg.h"
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37#define CR_MAX_WINDOWS 100
38#define CR_MAX_CLIENTS 64
39
40/*@todo must match MaxGuestMonitors from SchemaDefs.h*/
41#define CR_MAX_GUEST_MONITORS VBOX_VIDEO_MAX_SCREENS
42
43typedef DECLCALLBACKPTR(void, PFNCRSERVERPRESENTFBO) (void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h);
44
45/* Callbacks for output of the rendered frames.
46 *
47 * This allows to pass rendered frames to an external component rather than draw them on screen.
48 *
49 * An external component registers the redirection callbacks using crVBoxServerOutputRedirectSet.
50 *
51 * The list of formats supported by the caller is obtained using CRORContextProperty.
52 * The actual format choosed by the service is passed as a CRORBegin parameter.
53 */
54typedef struct {
55 const void *pvContext; /* Supplied by crVBoxServerOutputRedirectSet. */
56 DECLR3CALLBACKMEMBER(void, CRORBegin, (const void *pvContext, void **ppvInstance,
57 const char *pszFormat));
58 DECLR3CALLBACKMEMBER(void, CRORGeometry, (void *pvInstance,
59 int32_t x, int32_t y, uint32_t w, uint32_t h));
60 DECLR3CALLBACKMEMBER(void, CRORVisibleRegion, (void *pvInstance,
61 uint32_t cRects, const RTRECT *paRects));
62 DECLR3CALLBACKMEMBER(void, CRORFrame, (void *pvInstance,
63 void *pvData, uint32_t cbData));
64 DECLR3CALLBACKMEMBER(void, CROREnd, (void *pvInstance));
65 DECLR3CALLBACKMEMBER(int, CRORContextProperty, (const void *pvContext, uint32_t index,
66 void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut));
67} CROutputRedirect;
68
69typedef struct {
70 CRrecti imagewindow; /**< coordinates in mural space */
71 CRrectf bounds; /**< normalized coordinates in [-1,-1] x [1,1] */
72 CRrecti outputwindow; /**< coordinates in server's rendering window */
73 CRrecti clippedImagewindow; /**< imagewindow clipped to current viewport */
74 CRmatrix baseProjection; /**< pre-multiplied onto projection matrix */
75 CRrecti scissorBox; /**< passed to back-end OpenGL */
76 CRrecti viewport; /**< passed to back-end OpenGL */
77 GLuint serialNo; /**< an optimization */
78} CRExtent;
79
80struct BucketingInfo;
81
82typedef struct {
83 char *pszDpyName;
84 GLint visualBits;
85 int32_t externalID;
86} CRCreateInfo_t;
87
88/**
89 * Mural info
90 */
91typedef struct {
92 GLuint width, height;
93 GLint gX, gY; /*guest coordinates*/
94 GLint hX, hY; /*host coordinates, screenID related*/
95
96 int spuWindow; /*the SPU's corresponding window ID */
97
98 int screenId;
99
100 GLboolean bVisible; /*guest window is visible*/
101 GLubyte fUseFBO; /*redirect to FBO instead of real host window*/
102 GLboolean bFbDraw; /*GL_FRONT buffer is drawn to directly*/
103
104 GLint cVisibleRects; /*count of visible rects*/
105 GLint *pVisibleRects; /*visible rects left, top, right, bottom*/
106 GLboolean bReceivedRects; /*indicates if guest did any updates for visible regions*/
107
108 GLuint cBuffers;
109 GLuint iBbBuffer;
110 GLuint aidFBOs[2];
111 GLuint aidColorTexs[2];
112
113 void *pvOutputRedirectInstance;
114
115 CRCreateInfo_t CreateInfo;
116
117 /* to avoid saved state breakage we need to keep RT_OFFSETOF(CRMuralInfo, CreateInfo) intact
118 * this is why we place some FBO stuff to the tail
119 * @todo: once we need to increment a saved state version, we could refactor this structure */
120 GLuint iCurDrawBuffer;
121 GLuint iCurReadBuffer;
122
123 GLuint idDepthStencilRB;
124 GLuint fboWidth, fboHeight;
125 GLuint idPBO;
126
127 VBOXVR_SCR_COMPOSITOR_ENTRY CEntry;
128 VBOXVR_SCR_COMPOSITOR Compositor;
129
130 /* bitfield representing contexts the mural has been ever current with
131 * we just reuse CR_STATE_SHAREDOBJ_USAGE_XXX API here for simplicity */
132 CRbitvalue ctxUsage[CR_MAX_BITARRAY];
133} CRMuralInfo;
134
135typedef struct {
136 CRContext *pContext;
137 int SpuContext;
138 CRCreateInfo_t CreateInfo;
139 CRMuralInfo * currentMural;
140} CRContextInfo;
141
142/**
143 * A client is basically an upstream Cr Node (connected via mothership)
144 */
145typedef struct _crclient {
146 int spu_id; /**< id of the last SPU in the client's SPU chain */
147 CRConnection *conn; /**< network connection from the client */
148 int number; /**< a unique number for each client */
149 uint64_t pid; /*guest pid*/
150 GLint currentContextNumber;
151 CRContextInfo *currentCtxInfo;
152 GLint currentWindow;
153 CRMuralInfo *currentMural;
154 GLint windowList[CR_MAX_WINDOWS];
155 GLint contextList[CR_MAX_CONTEXTS];
156#ifdef VBOXCR_LOGFPS
157 uint64_t timeUsed;
158#endif
159} CRClient;
160
161typedef struct _crclientnode {
162 CRClient *pClient;
163 struct _crclientnode *prev, *next;
164} CRClientNode;
165
166typedef struct CRPoly_t {
167 int npoints;
168 double *points;
169 struct CRPoly_t *next;
170} CRPoly;
171
172/**
173 * There's one of these run queue entries per client
174 * The run queue is a circular, doubly-linked list of these objects.
175 */
176typedef struct RunQueue_t {
177 CRClient *client;
178 int blocked;
179 struct RunQueue_t *next;
180 struct RunQueue_t *prev;
181} RunQueue;
182
183typedef struct {
184 GLint freeWindowID;
185 GLint freeContextID;
186 GLint freeClientID;
187} CRServerFreeIDsPool_t;
188
189typedef struct {
190 int32_t x, y;
191 uint32_t w, h;
192 uint64_t winID;
193} CRScreenInfo;
194
195typedef struct {
196 int32_t x, y;
197 uint32_t w, h;
198} CRScreenViewportInfo;
199
200
201/* DISPLAY */
202
203typedef struct CR_DISPLAY_ENTRY
204{
205 VBOXVR_SCR_COMPOSITOR_ENTRY CEntry;
206} CR_DISPLAY_ENTRY, *PCR_DISPLAY_ENTRY;
207
208/* @todo:
209 * 1. use compositor stored inside mural to use current MuralFBO and window-related API
210 * 2. CR_SERVER_REDIR_NONE and CR_SERVER_REDIR_FBO_BLT should be trated identically for presented window
211 * since we just need to blit the given textures to it if we are NOT in CR_SERVER_REDIR_FBO_RAM mode */
212typedef struct CR_DISPLAY
213{
214 VBOXVR_SCR_COMPOSITOR Compositor;
215 CRMuralInfo Mural;
216} CR_DISPLAY, *PCR_DISPLAY;
217
218int CrDpInit(PCR_DISPLAY pDisplay);
219void CrDpTerm(PCR_DISPLAY pDisplay);
220void CrDpResize(PCR_DISPLAY pDisplay, uint32_t width, uint32_t height,
221 uint32_t stretchedWidth, uint32_t stretchedHeight);
222void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const PVBOXVR_TEXTURE pTextureData);
223void CrDpEntryCleanup(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry);
224int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions);
225int CrDpEntryRegionsAdd(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions);
226int CrDpPresentEntry(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry);
227DECLINLINE(bool) CrDpEntryIsUsed(PCR_DISPLAY_ENTRY pEntry)
228{
229 return CrVrScrCompositorEntryIsInList(&pEntry->CEntry);
230}
231
232DECLINLINE(CRMuralInfo*) CrDpGetMural(PCR_DISPLAY pDisplay)
233{
234 return &pDisplay->Mural;
235}
236
237typedef struct CR_DISPLAY_ENTRY_MAP
238{
239 CRHashTable * pTextureMap;
240} CR_DISPLAY_ENTRY_MAP, *PCR_DISPLAY_ENTRY_MAP;
241
242int CrDemInit(PCR_DISPLAY_ENTRY_MAP pMap);
243void CrDemTerm(PCR_DISPLAY_ENTRY_MAP pMap);
244PCR_DISPLAY_ENTRY CrDemEntryGetCreate(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture, CRContextInfo *pCtxInfo);
245void CrDemEntryDestroy(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture);
246
247/* */
248
249/* helpers */
250
251void CrHlpFreeTexImage(CRContext *pCurCtx, GLuint idPBO, void *pvData);
252void* CrHlpGetTexImage(CRContext *pCurCtx, PVBOXVR_TEXTURE pTexture, GLuint idPBO, GLenum enmFormat);
253void CrHlpPutTexImage(CRContext *pCurCtx, PVBOXVR_TEXTURE pTexture, GLenum enmFormat, void *pvData);
254
255/* */
256
257typedef struct {
258 unsigned short tcpip_port;
259
260 CRScreenInfo screen[CR_MAX_GUEST_MONITORS];
261 CRScreenViewportInfo screenVieport[CR_MAX_GUEST_MONITORS];
262 int screenCount;
263
264 int numClients;
265 CRClient *clients[CR_MAX_CLIENTS]; /**< array [numClients] */
266 CRClient *curClient;
267 CRClientNode *pCleanupClient; /*list of clients with pending clean up*/
268 CRCurrentStatePointers current;
269
270 GLboolean firstCallCreateContext;
271 GLboolean firstCallMakeCurrent;
272 GLboolean bIsInLoadingState; /* Indicates if we're in process of loading VM snapshot */
273 GLboolean bIsInSavingState; /* Indicates if we're in process of saving VM snapshot */
274 GLboolean bForceMakeCurrentOnClientSwitch;
275 CRContextInfo *currentCtxInfo;
276 GLint currentWindow;
277 GLint currentNativeWindow;
278 CRMuralInfo *currentMural;
279
280 CRHashTable *muralTable; /**< hash table where all murals are stored */
281
282 int client_spu_id;
283
284 int mtu;
285 int buffer_size;
286 char protocol[1024];
287
288 SPU *head_spu;
289 SPUDispatchTable dispatch;
290
291 CRNetworkPointer return_ptr;
292 CRNetworkPointer writeback_ptr;
293
294 CRLimitsState limits; /**< GL limits for any contexts we create */
295
296 CRContextInfo MainContextInfo;
297
298 CRHashTable *contextTable; /**< hash table for rendering contexts */
299
300 CRHashTable *programTable; /**< for vertex programs */
301 GLuint currentProgram;
302
303 /* visBits -> dummy mural association */
304 CRHashTable *dummyMuralTable;
305
306 /** configuration options */
307 /*@{*/
308 int useL2;
309 int ignore_papi;
310 unsigned int maxBarrierCount;
311 unsigned int clearCount;
312 int optimizeBucket;
313 int only_swap_once;
314 int debug_barriers;
315 int sharedDisplayLists;
316 int sharedTextureObjects;
317 int sharedPrograms;
318 int sharedWindows;
319 int uniqueWindows;
320 int localTileSpec;
321 int useDMX;
322 int overlapBlending;
323 int vpProjectionMatrixParameter;
324 const char *vpProjectionMatrixVariable;
325 int stereoView;
326 int vncMode; /* cmd line option */
327 /*@}*/
328 /** view_matrix config */
329 /*@{*/
330 GLboolean viewOverride;
331 CRmatrix viewMatrix[2]; /**< left and right eye */
332 /*@}*/
333 /** projection_matrix config */
334 /*@{*/
335 GLboolean projectionOverride;
336 CRmatrix projectionMatrix[2]; /**< left and right eye */
337 int currentEye;
338 /*@}*/
339
340 /** for warped tiles */
341 /*@{*/
342 GLfloat alignment_matrix[16], unnormalized_alignment_matrix[16];
343 /*@}*/
344
345 /** tile overlap/blending info - this should probably be per-mural */
346 /*@{*/
347 CRPoly **overlap_geom;
348 CRPoly *overlap_knockout;
349 float *overlap_intens;
350 int num_overlap_intens;
351 int num_overlap_levels;
352 /*@}*/
353
354 CRHashTable *barriers, *semaphores;
355
356 RunQueue *run_queue;
357
358 GLuint currentSerialNo;
359
360 PFNCRSERVERPRESENTFBO pfnPresentFBO;
361 GLubyte bForceOffscreenRendering; /*Force server to render 3d data offscreen
362 *using callback above to update vbox framebuffers*/
363 GLubyte bOffscreenRenderingDefault; /*can be set with CR_SERVER_DEFAULT_RENDER_TYPE*/
364 GLboolean bUsePBOForReadback; /*Use PBO's for data readback*/
365
366 GLboolean bUseOutputRedirect; /* Whether the output redirect was set. */
367 CROutputRedirect outputRedirect;
368
369 GLboolean bUseMultipleContexts;
370
371 /* @todo: should we use just one blitter?
372 * we use two currently because the drawable attribs can differ*/
373 CR_DISPLAY_ENTRY_MAP PresentTexturepMap;
374 uint32_t DisplaysInitMap[(CR_MAX_GUEST_MONITORS + 31)/32];
375 CR_DISPLAY aDispplays[CR_MAX_GUEST_MONITORS];
376} CRServer;
377
378
379extern DECLEXPORT(void) crServerInit( int argc, char *argv[] );
380extern DECLEXPORT(int) CRServerMain( int argc, char *argv[] );
381extern DECLEXPORT(void) crServerServiceClients(void);
382extern DECLEXPORT(void) crServerAddNewClient(void);
383extern DECLEXPORT(SPU*) crServerHeadSPU(void);
384extern DECLEXPORT(void) crServerSetPort(int port);
385
386extern DECLEXPORT(GLboolean) crVBoxServerInit(void);
387extern DECLEXPORT(void) crVBoxServerTearDown(void);
388extern DECLEXPORT(int32_t) crVBoxServerAddClient(uint32_t u32ClientID);
389extern DECLEXPORT(void) crVBoxServerRemoveClient(uint32_t u32ClientID);
390extern DECLEXPORT(int32_t) crVBoxServerClientWrite(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t cbBuffer);
391extern DECLEXPORT(int32_t) crVBoxServerClientRead(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t *pcbBuffer);
392extern DECLEXPORT(int32_t) crVBoxServerClientSetVersion(uint32_t u32ClientID, uint32_t vMajor, uint32_t vMinor);
393extern DECLEXPORT(int32_t) crVBoxServerClientSetPID(uint32_t u32ClientID, uint64_t pid);
394
395extern DECLEXPORT(int32_t) crVBoxServerSaveState(PSSMHANDLE pSSM);
396extern DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version);
397
398extern DECLEXPORT(int32_t) crVBoxServerSetScreenCount(int sCount);
399extern DECLEXPORT(int32_t) crVBoxServerUnmapScreen(int sIndex);
400extern DECLEXPORT(int32_t) crVBoxServerMapScreen(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h, uint64_t winID);
401
402extern DECLEXPORT(int32_t) crVBoxServerSetRootVisibleRegion(GLint cRects, GLint *pRects);
403
404extern DECLEXPORT(void) crVBoxServerSetPresentFBOCB(PFNCRSERVERPRESENTFBO pfnPresentFBO);
405
406extern DECLEXPORT(int32_t) crVBoxServerSetOffscreenRendering(GLboolean value);
407
408extern DECLEXPORT(int32_t) crVBoxServerOutputRedirectSet(const CROutputRedirect *pCallbacks);
409
410extern DECLEXPORT(int32_t) crVBoxServerSetScreenViewport(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h);
411
412#ifdef VBOX_WITH_CRHGSMI
413/* We moved all CrHgsmi command processing to crserverlib to keep the logic of dealing with CrHgsmi commands in one place.
414 *
415 * For now we need the notion of CrHgdmi commands in the crserver_lib to be able to complete it asynchronously once it is really processed.
416 * This help avoiding the "blocked-client" issues. The client is blocked if another client is doing begin-end stuff.
417 * For now we eliminated polling that could occur on block, which caused a higher-priority thread (in guest) polling for the blocked command complition
418 * to block the lower-priority thread trying to complete the blocking command.
419 * And removed extra memcpy done on blocked command arrival.
420 *
421 * In the future we will extend CrHgsmi functionality to maintain texture data directly in CrHgsmi allocation to avoid extra memcpy-ing with PBO,
422 * implement command completion and stuff necessary for GPU scheduling to work properly for WDDM Windows guests, etc.
423 *
424 * NOTE: it is ALWAYS responsibility of the crVBoxServerCrHgsmiCmd to complete the command!
425 * */
426extern DECLEXPORT(int32_t) crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t cbCmd);
427extern DECLEXPORT(int32_t) crVBoxServerCrHgsmiCtl(struct VBOXVDMACMD_CHROMIUM_CTL *pCtl, uint32_t cbCtl);
428#endif
429
430#ifdef __cplusplus
431}
432#endif
433
434#endif
435
Note: See TracBrowser for help on using the repository browser.

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