1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
|
/* Copyright (c) 2001, Stanford University
* All rights reserved.
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#ifndef INCLUDE_CR_SERVER_H
#define INCLUDE_CR_SERVER_H
#include "cr_spu.h"
#include "cr_net.h"
#include "cr_hash.h"
#include "cr_protocol.h"
#include "cr_glstate.h"
#include "cr_vreg.h"
#include "cr_blitter.h"
#include "cr_htable.h"
#include "spu_dispatch_table.h"
#include "cr_dump.h"
#include "state/cr_currentpointers.h"
#include <iprt/types.h>
#include <iprt/err.h>
#include <iprt/string.h>
#include <iprt/list.h>
#include <iprt/thread.h>
#include <iprt/critsect.h>
#include <iprt/semaphore.h>
#include <iprt/memcache.h>
#include <VBox/vmm/ssm.h>
#include <VBoxVideo.h>
#include <VBoxVideoVBE.h>
#include <VBoxVideo3D.h>
#include <VBoxVideoHost3D.h>
#ifdef __cplusplus
extern "C" {
#endif
#define CR_MAX_WINDOWS 100
#define CR_MAX_CLIENTS 64
/** @todo must match MaxGuestMonitors from SchemaDefs.h*/
#define CR_MAX_GUEST_MONITORS VBOX_VIDEO_MAX_SCREENS
typedef DECLCALLBACKPTR(void, PFNCRSERVERPRESENTFBO) (void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h);
/* Callbacks for output of the rendered frames.
*
* This allows to pass rendered frames to an external component rather than draw them on screen.
*
* An external component registers the redirection callbacks using crVBoxServerOutputRedirectSet.
*
* The list of formats supported by the caller is obtained using CRORContextProperty.
* The actual format choosed by the service is passed as a CRORBegin parameter.
*/
typedef struct {
const void *pvContext; /* Supplied by crVBoxServerOutputRedirectSet. */
DECLR3CALLBACKMEMBER(void, CRORBegin, (const void *pvContext, void **ppvInstance,
const char *pszFormat));
DECLR3CALLBACKMEMBER(void, CRORGeometry, (void *pvInstance,
int32_t x, int32_t y, uint32_t w, uint32_t h));
DECLR3CALLBACKMEMBER(void, CRORVisibleRegion, (void *pvInstance,
uint32_t cRects, const RTRECT *paRects));
DECLR3CALLBACKMEMBER(void, CRORFrame, (void *pvInstance,
void *pvData, uint32_t cbData));
DECLR3CALLBACKMEMBER(void, CROREnd, (void *pvInstance));
DECLR3CALLBACKMEMBER(int, CRORContextProperty, (const void *pvContext, uint32_t index,
void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut));
} CROutputRedirect;
typedef struct {
CRrecti imagewindow; /**< coordinates in mural space */
CRrectf bounds; /**< normalized coordinates in [-1,-1] x [1,1] */
CRrecti outputwindow; /**< coordinates in server's rendering window */
CRrecti clippedImagewindow; /**< imagewindow clipped to current viewport */
CRmatrix baseProjection; /**< pre-multiplied onto projection matrix */
CRrecti scissorBox; /**< passed to back-end OpenGL */
CRrecti viewport; /**< passed to back-end OpenGL */
GLuint serialNo; /**< an optimization */
} CRExtent;
struct BucketingInfo;
typedef struct {
char *pszDpyName;
GLint visualBits;
int32_t externalID;
} CRCreateInfo_t;
typedef struct {
char *pszDpyName;
int32_t externalID;
GLint requestedVisualBits;
GLint realVisualBits;
} CRCreateInfoEx_t;
/* VRAM->RAM worker thread */
typedef enum
{
CR_SERVER_RPW_STATE_UNINITIALIZED = 0,
CR_SERVER_RPW_STATE_INITIALIZING,
CR_SERVER_RPW_STATE_INITIALIZED,
CR_SERVER_RPW_STATE_UNINITIALIZING,
} CR_SERVER_RPW_STATE;
/* worker control command */
typedef enum
{
CR_SERVER_RPW_CTL_TYPE_UNDEFINED = 0,
CR_SERVER_RPW_CTL_TYPE_WAIT_COMPLETE,
CR_SERVER_RPW_CTL_TYPE_TERM
} CR_SERVER_RPW_CTL_TYPE;
struct CR_SERVER_RPW_ENTRY;
typedef struct CR_SERVER_RPW_CTL {
CR_SERVER_RPW_CTL_TYPE enmType;
int rc;
RTSEMEVENT hCompleteEvent;
/* valid for *_WAIT_COMPLETE and *_CANCEL */
struct CR_SERVER_RPW_ENTRY *pEntry;
} CR_SERVER_RPW_CTL;
struct CR_SERVER_RPW_ENTRY;
typedef DECLCALLBACKPTR(void, PFNCR_SERVER_RPW_DATA) (const struct CR_SERVER_RPW_ENTRY* pEntry, void *pvEntryTexData);
typedef DECLCALLBACKPTR(void, PFNCRSERVERNOTIFYEVENT) (int32_t screenId, uint32_t uEvent, void* pvData, uint32_t cbData);
typedef struct CR_SERVER_RPW_ENTRY
{
RTRECTSIZE Size;
/* We have to use 4 textures here.
*
* 1. iDrawTex - the texture clients can draw to and then submit it for contents acquisition via crServerRpwEntrySubmit
* 2. iSubmittedTex - the texture submitted to the worker for processing and, whose processing has not start yet,
* i.e. it is being in the queue and can be safely removed/replaced [from] there
* 3. iWorkerTex - the texture being prepared & passed by the worker to the GPU (stage 1 of a worker contents acquisition process)
* 4. iGpuTex - the texture passed/processed to/by the GPU, whose data is then acquired by the server (stage 2 of a worker contents acquisition process)
*
* - There can be valid distinct iGpuTex, iWorkerTex, iSubmittedTex and iDrawTex present simultaneously.
* - Either or both of iSubmittedTex and iFreeTex are always valid
*
* Detail:
*
* - iSubmittedTex and iFreeTex modifications are performed under CR_SERVER_RPW::CritSect lock.
*
* - iDrawTex can only be changed by client side (i.e. the crServerRpwEntrySubmit caller), this is why client thread can access it w/o a lock
* - iSubmittedTex and iFreeTex can be modified by both client and worker, so lock is always required
*
* - iDrawTex can be accessed by client code only
* - iWorkerTex and iGpuTex can be accessed by worker code only
* - iSubmittedTex and iFreeTex can be accessed under CR_SERVER_RPW::CritSect lock only
* - either or both of iSubmittedTex and iFreeTex are always valid (see below for more explanation),
* this is why client can easily determine the new iDrawTex value on Submit, i.e. :
*
* (if initial iSubmittedTex was valid)
* ---------------
* | ^
* > |
* Submit-> iDrawTex -> iSubmittedTex
* ^
* | (if initial iSubmittedTex was NOT valid)
* iFreeTex
*
* - The worker can invalidate the iSubmittedTex (i.e. do iSubmittedTex -> iWorkerTex) only after it is done
* with the last iWorkerTex -> iGpuTex transformation freeing the previously used iGpuTex to iFreeTex.
*
* - A simplified worker iXxxTex transformation logic is:
* 1. iFreeTex is initially valid
* 2. iSubmittedTex -> iWorkerTex;
* 3. submit iWorkerTex acquire request to the GPU
* 4. complete current iGpuTex
* 5. iGpuTex -> iFreeTex
* 6. iWorkerTex -> iGpuTex
* 7. goto 1
*
* */
int8_t iTexDraw;
int8_t iTexSubmitted;
int8_t iTexWorker;
int8_t iTexGpu;
int8_t iCurPBO;
GLuint aidWorkerTexs[4];
GLuint aidPBOs[2];
RTLISTNODE WorkEntry;
RTLISTNODE WorkerWorkEntry;
RTLISTNODE GpuSubmittedEntry;
PFNCR_SERVER_RPW_DATA pfnData;
} CR_SERVER_RPW_ENTRY;
typedef struct CR_SERVER_RPW {
RTLISTNODE WorkList;
RTCRITSECT CritSect;
RTSEMEVENT hSubmitEvent;
/* only one outstanding command is supported,
* and ctl requests must be cynchronized, hold it right here */
CR_SERVER_RPW_CTL Ctl;
int ctxId;
GLint ctxVisBits;
RTTHREAD hThread;
} CR_SERVER_RPW;
/* */
/* FRAMEBUFFER */
typedef struct CR_FRAMEBUFFER *HCR_FRAMEBUFFER;
typedef struct CR_FRAMEBUFFER_ENTRY *HCR_FRAMEBUFFER_ENTRY;
/* */
typedef struct CR_FBDATA
{
HCR_FRAMEBUFFER hFb;
HCR_FRAMEBUFFER_ENTRY hFbEntry;
CR_TEXDATA* apTexDatas[2];
} CR_FBDATA;
/**
* Mural info
*/
typedef struct {
GLuint width, height;
GLint gX, gY; /*guest coordinates*/
GLint hX, hY; /*host coordinates, screenID related*/
int spuWindow; /*the SPU's corresponding window ID */
int screenId;
GLboolean bVisible; /*guest window is visible*/
GLubyte u8Unused; /*redirect to FBO instead of real host window*/
GLboolean bFbDraw; /*GL_FRONT buffer is drawn to directly*/
GLboolean fIsDummyRefference;
GLint cVisibleRects; /*count of visible rects*/
GLint *pVisibleRects; /*visible rects left, top, right, bottom*/
GLboolean bReceivedRects; /*indicates if guest did any updates for visible regions*/
GLuint cBuffers;
GLuint iBbBuffer;
GLuint aidFBOs[2];
GLuint aidColorTexs[2];
void *pvReserved;
CRCreateInfoEx_t CreateInfo;
/* to avoid saved state breakage we need to keep RT_OFFSETOF(CRMuralInfo, CreateInfo) intact
* this is why we place some FBO stuff to the tail
* @todo: once we need to increment a saved state version, we could refactor this structure */
GLint iCurDrawBuffer;
GLint iCurReadBuffer;
GLuint idDepthStencilRB;
GLuint fboWidth, fboHeight;
GLboolean fHasParentWindow;
GLboolean fRedirected;
GLboolean fForcePresentState;
GLboolean fOrPresentOnReenable;
GLboolean fIsVisible;
CR_TEXDATA aTexs[2];
uint32_t cUsedFBDatas;
CR_FBDATA *apUsedFBDatas[CR_MAX_GUEST_MONITORS];
CR_FBDATA aFBDatas[CR_MAX_GUEST_MONITORS];
/* bitfield representing contexts the mural has been ever current with
* we just reuse CR_STATE_SHAREDOBJ_USAGE_XXX API here for simplicity */
CRbitvalue ctxUsage[CR_MAX_BITARRAY];
} CRMuralInfo;
typedef struct {
CRContext *pContext;
int SpuContext;
CRCreateInfoEx_t CreateInfo;
CRMuralInfo * currentMural;
} CRContextInfo;
/**
* A client is basically an upstream Cr Node (connected via mothership)
*/
typedef struct _crclient {
int spu_id; /**< id of the last SPU in the client's SPU chain */
CRConnection *conn; /**< network connection from the client */
int number; /**< a unique number for each client */
uint64_t pid; /*guest pid*/
GLint currentContextNumber;
CRContextInfo *currentCtxInfo;
GLint currentWindow;
CRMuralInfo *currentMural;
GLint windowList[CR_MAX_WINDOWS];
GLint contextList[CR_MAX_CONTEXTS];
#ifdef VBOXCR_LOGFPS
uint64_t timeUsed;
#endif
} CRClient;
typedef struct _crclientnode {
CRClient *pClient;
struct _crclientnode *prev, *next;
} CRClientNode;
typedef struct CRPoly_t {
int npoints;
double *points;
struct CRPoly_t *next;
} CRPoly;
/**
* There's one of these run queue entries per client
* The run queue is a circular, doubly-linked list of these objects.
*/
typedef struct RunQueue_t {
CRClient *client;
int blocked;
struct RunQueue_t *next;
struct RunQueue_t *prev;
} RunQueue;
typedef struct {
GLint freeWindowID;
GLint freeContextID;
GLint freeClientID;
} CRServerFreeIDsPool_t;
typedef struct {
int32_t x, y;
uint32_t w, h;
uint64_t winID;
} CRScreenInfo;
typedef struct {
RTRECT Rect;
} CRScreenViewportInfo;
/* BFB (BlitFramebuffer Blitter) flags
* so far only CR_SERVER_BFB_ON_ALWAIS is supported and is alwais used if any flag is set */
#define CR_SERVER_BFB_DISABLED 0
#define CR_SERVER_BFB_ON_INVERTED_BLIT 1
#define CR_SERVER_BFB_ON_STRAIGHT_BLIT 2
#define CR_SERVER_BFB_ON_ALWAIS (CR_SERVER_BFB_ON_INVERTED_BLIT | CR_SERVER_BFB_ON_STRAIGHT_BLIT)
typedef struct {
unsigned short tcpip_port;
CRScreenInfo screen[CR_MAX_GUEST_MONITORS];
CRScreenViewportInfo screenVieport[CR_MAX_GUEST_MONITORS];
int screenCount;
GLboolean fCrCmdEnabled;
GLboolean fProcessingPendedCommands;
int numClients;
CRClient *clients[CR_MAX_CLIENTS]; /**< array [numClients] */
CRClient *curClient;
CRClientNode *pCleanupClient; /*list of clients with pending clean up*/
CRHTABLE clientTable;
CRCurrentStatePointers current;
GLboolean firstCallCreateContext;
GLboolean firstCallMakeCurrent;
GLboolean bIsInLoadingState; /* Indicates if we're in process of loading VM snapshot */
GLboolean bIsInSavingState; /* Indicates if we're in process of saving VM snapshot */
GLboolean bForceMakeCurrentOnClientSwitch;
CRContextInfo *currentCtxInfo;
GLint currentWindow;
GLint currentNativeWindow;
CRMuralInfo *currentMural;
CRHashTable *muralTable; /**< hash table where all murals are stored */
int client_spu_id;
int mtu;
int buffer_size;
char protocol[1024];
SPU *head_spu;
SPUDispatchTable dispatch;
CRNetworkPointer return_ptr;
CRNetworkPointer writeback_ptr;
CRLimitsState limits; /**< GL limits for any contexts we create */
CRContextInfo MainContextInfo;
CRHashTable *contextTable; /**< hash table for rendering contexts */
CRHashTable *programTable; /**< for vertex programs */
GLuint currentProgram;
/* visBits -> dummy mural association */
CRHashTable *dummyMuralTable;
GLboolean fRootVrOn;
VBOXVR_LIST RootVr;
/* we need to translate Root Vr to each window coords, this one cpecifies the current translation point
* note that since window attributes modifications is performed in HGCM thread only and thus is serialized,
* we deal with the global RootVr data directly */
RTPOINT RootVrCurPoint;
/* blitter so far used for working around host drivers BlitFramebuffer bugs
* by implementing */
uint32_t fBlitterMode;
CR_BLITTER Blitter;
CR_SERVER_RPW RpwWorker;
VBOXCRCMDCTL_HGCMDISABLE_DATA DisableData;
RTSEMEVENT hCalloutCompletionEvent;
VBOXCRCMDCTL *pCurrentCalloutCtl;
VBOXCRCLIENT_INFO ClientInfo;
/** configuration options */
/*@{*/
int useL2;
int ignore_papi;
unsigned int maxBarrierCount;
unsigned int clearCount;
int optimizeBucket;
int only_swap_once;
int debug_barriers;
int sharedDisplayLists;
int sharedTextureObjects;
int sharedPrograms;
int sharedWindows;
int uniqueWindows;
int localTileSpec;
int useDMX;
int overlapBlending;
int vpProjectionMatrixParameter;
const char *vpProjectionMatrixVariable;
int stereoView;
int vncMode; /* cmd line option */
/*@}*/
/** view_matrix config */
/*@{*/
GLboolean viewOverride;
CRmatrix viewMatrix[2]; /**< left and right eye */
/*@}*/
/** projection_matrix config */
/*@{*/
GLboolean projectionOverride;
CRmatrix projectionMatrix[2]; /**< left and right eye */
int currentEye;
/*@}*/
/** for warped tiles */
/*@{*/
GLfloat alignment_matrix[16], unnormalized_alignment_matrix[16];
/*@}*/
/** tile overlap/blending info - this should probably be per-mural */
/*@{*/
CRPoly **overlap_geom;
CRPoly *overlap_knockout;
float *overlap_intens;
int num_overlap_intens;
int num_overlap_levels;
/*@}*/
CRHashTable *barriers, *semaphores;
RunQueue *run_queue;
GLuint currentSerialNo;
GLuint fVisualBitsDefault;
GLboolean bUsePBOForReadback; /*Use PBO's for data readback*/
CROutputRedirect outputRedirect;
GLboolean bUseMultipleContexts;
GLboolean bWindowsInitiallyHidden;
/* OR-ed CR_VBOX_CAP_XXX cap values
* describing VBox Chromium functionality caps visible to guest
* Currently can have only CR_VBOX_CAP_TEX_PRESENT cap to notify
* that the TexPresent mechanism is available and enabled */
uint32_t u32Caps;
PFNCRSERVERNOTIFYEVENT pfnNotifyEventCB;
SPUDispatchTable TmpCtxDispatch;
VBOXCRCMD_SVRENABLE_INFO CrCmdClientInfo;
#ifdef VBOX_WITH_CRSERVER_DUMPER
CR_RECORDER Recorder;
CR_BLITTER RecorderBlitter;
CR_DBGPRINT_DUMPER DbgPrintDumper;
CR_HTML_DUMPER HtmlDumper;
CR_DUMPER *pDumper;
#endif
int RcToGuest;
int RcToGuestOnce;
} CRServer;
extern DECLEXPORT(void) crServerInit( int argc, char *argv[] );
extern DECLEXPORT(int) CRServerMain( int argc, char *argv[] );
extern DECLEXPORT(void) crServerServiceClients(void);
extern DECLEXPORT(void) crServerAddNewClient(void);
extern DECLEXPORT(SPU*) crServerHeadSPU(void);
extern DECLEXPORT(void) crServerSetPort(int port);
extern DECLEXPORT(GLboolean) crVBoxServerInit(void);
extern DECLEXPORT(void) crVBoxServerTearDown(void);
extern DECLEXPORT(int32_t) crVBoxServerAddClient(uint32_t u32ClientID);
extern DECLEXPORT(void) crVBoxServerRemoveClient(uint32_t u32ClientID);
extern DECLEXPORT(int32_t) crVBoxServerClientWrite(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t cbBuffer);
extern DECLEXPORT(int32_t) crVBoxServerClientRead(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t *pcbBuffer);
extern DECLEXPORT(int32_t) crVBoxServerClientSetVersion(uint32_t u32ClientID, uint32_t vMajor, uint32_t vMinor);
extern DECLEXPORT(int32_t) crVBoxServerClientGetCapsLegacy(uint32_t u32ClientID, uint32_t *pu32Caps);
extern DECLEXPORT(int32_t) crVBoxServerClientGetCapsNew(uint32_t u32ClientID, CR_CAPS_INFO *pInfo);
extern DECLEXPORT(int32_t) crVBoxServerClientSetPID(uint32_t u32ClientID, uint64_t pid);
extern DECLEXPORT(int32_t) crVBoxServerSaveState(PSSMHANDLE pSSM);
extern DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version);
typedef struct
{
CR_BLITTER_IMG Img;
uint32_t u32Screen;
uint32_t fDataAllocated;
} CR_SCREENSHOT;
extern DECLEXPORT(int) crServerVBoxWindowsShow(bool fShow);
extern DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, uint32_t width, uint32_t height, uint32_t pitch, void *pvBuffer, CR_SCREENSHOT *pScreenshot);
extern DECLEXPORT(void) crServerVBoxScreenshotRelease(CR_SCREENSHOT *pScreenshot);
extern DECLEXPORT(void) crServerVBoxCompositionSetEnableStateGlobal(GLboolean fEnable);
extern DECLEXPORT(int32_t) crVBoxServerSetScreenCount(int sCount);
extern DECLEXPORT(int32_t) crVBoxServerUnmapScreen(int sIndex);
extern DECLEXPORT(int32_t) crVBoxServerMapScreen(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h, uint64_t winID);
extern DECLEXPORT(void) crServerVBoxCompositionSetEnableStateGlobal(GLboolean fEnable);
struct VBVAINFOSCREEN;
extern DECLEXPORT(int) crVBoxServerNotifyResize(const struct VBVAINFOSCREEN *pScreen, void *pvVRAM);
extern DECLEXPORT(int32_t) crVBoxServerSetRootVisibleRegion(GLint cRects, const RTRECT *pRects);
extern DECLEXPORT(int32_t) crVBoxServerSetOffscreenRendering(GLboolean value);
extern DECLEXPORT(int32_t) crVBoxServerOutputRedirectSet(const CROutputRedirect *pCallbacks);
extern DECLEXPORT(int32_t) crVBoxServerSetScreenViewport(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h);
extern DECLEXPORT(void) crServerVBoxSetNotifyEventCB(PFNCRSERVERNOTIFYEVENT pfnCb);
extern DECLEXPORT(void) crVBoxServerCalloutEnable(VBOXCRCMDCTL *pCtl);
extern DECLEXPORT(void) crVBoxServerCalloutDisable(void);
extern DECLEXPORT(void) crServerSetUnscaledHiDPI(bool fEnable);
#ifdef VBOX_WITH_CRHGSMI
/* We moved all CrHgsmi command processing to crserverlib to keep the logic of dealing with CrHgsmi commands in one place.
*
* 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.
* This help avoiding the "blocked-client" issues. The client is blocked if another client is doing begin-end stuff.
* For now we eliminated polling that could occur on block, which caused a higher-priority thread (in guest) polling for the blocked command complition
* to block the lower-priority thread trying to complete the blocking command.
* And removed extra memcpy done on blocked command arrival.
*
* In the future we will extend CrHgsmi functionality to maintain texture data directly in CrHgsmi allocation to avoid extra memcpy-ing with PBO,
* implement command completion and stuff necessary for GPU scheduling to work properly for WDDM Windows guests, etc.
*
* NOTE: it is ALWAYS responsibility of the crVBoxServerCrHgsmiCmd to complete the command!
* */
extern DECLEXPORT(int32_t) crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t cbCmd);
extern DECLEXPORT(int32_t) crVBoxServerCrHgsmiCtl(struct VBOXVDMACMD_CHROMIUM_CTL *pCtl, uint32_t cbCtl);
#endif
extern DECLEXPORT(int32_t) crVBoxServerHgcmEnable(VBOXCRCMDCTL_HGCMENABLE_DATA *pData);
extern DECLEXPORT(int32_t) crVBoxServerHgcmDisable(VBOXCRCMDCTL_HGCMDISABLE_DATA *pData);
extern int crVBoxServerHostCtl(VBOXCRCMDCTL *pCtl, uint32_t cbCtl);
#ifdef __cplusplus
}
#endif
#endif
|