- Timestamp:
- Jan 28, 2011 3:23:22 PM (14 years ago)
- Location:
- trunk/src/VBox/HostServices/SharedOpenGL
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
r35347 r35770 58 58 59 59 #include <VBox/com/errorprint.h> 60 #include <iprt/thread.h> 61 #include <iprt/critsect.h> 62 #include <iprt/semaphore.h> 63 #include <iprt/asm.h> 64 65 #include "cr_mem.h" 60 66 61 67 PVBOXHGCMSVCHELPERS g_pHelpers; … … 73 79 static const char* gszVBoxOGLSSMMagic = "***OpenGL state data***"; 74 80 81 /* Used to process guest calls exceeding maximum allowed HGCM call size in a sequence of smaller calls */ 75 82 typedef struct _CRVBOXSVCBUFFER_t { 76 83 uint32_t uiId; … … 83 90 static uint32_t g_CRVBoxSVCBufferID = 0; 84 91 92 /* svcPresentFBO related data */ 93 typedef struct _CRVBOXSVCPRESENTFBOCMD_t { 94 void *pData; 95 int32_t screenId, x, y, w, h; 96 _CRVBOXSVCPRESENTFBOCMD_t *pNext; 97 } CRVBOXSVCPRESENTFBOCMD_t, *PCRVBOXSVCPRESENTFBOCMD_t; 98 99 typedef struct _CRVBOXSVCPRESENTFBO_t { 100 PCRVBOXSVCPRESENTFBOCMD_t pQueueHead, pQueueTail; /* Head/Tail of FIFO cmds queue */ 101 RTCRITSECT hQueueLock; /* Queue lock */ 102 RTTHREAD hWorkerThread; /* Worker thread */ 103 bool volatile bShutdownWorker; /* Shutdown flag */ 104 RTSEMEVENT hEventProcess; /* Signalled when worker thread should process data or exit */ 105 } CRVBOXSVCPRESENTFBO_t; 106 107 static CRVBOXSVCPRESENTFBO_t g_SvcPresentFBO; 108 109 /* Schedule a call to a separate worker thread to avoid deadlock on EMT thread when the screen configuration changes 110 and we're processing crServerPresentFBO caused by guest application command. 111 To avoid unnecessary memcpy, worker thread frees the data passed. 112 */ 113 static DECLCALLBACK(void) svcPresentFBO(void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h) 114 { 115 PCRVBOXSVCPRESENTFBOCMD_t pCmd; 116 117 pCmd = (PCRVBOXSVCPRESENTFBOCMD_t) RTMemAlloc(sizeof(CRVBOXSVCPRESENTFBOCMD_t)); 118 if (!pCmd) 119 { 120 LogRel(("SHARED_CROPENGL svcPresentFBO: not enough memory (%d)\n", sizeof(CRVBOXSVCPRESENTFBOCMD_t))); 121 return; 122 } 123 pCmd->pData = data; 124 pCmd->screenId = screenId; 125 pCmd->x = x; 126 pCmd->y = y; 127 pCmd->w = w; 128 pCmd->h = h; 129 pCmd->pNext = NULL; 130 131 RTCritSectEnter(&g_SvcPresentFBO.hQueueLock); 132 133 if (g_SvcPresentFBO.pQueueTail) 134 { 135 g_SvcPresentFBO.pQueueTail->pNext = pCmd; 136 } 137 else 138 { 139 Assert(!g_SvcPresentFBO.pQueueHead); 140 g_SvcPresentFBO.pQueueHead = pCmd; 141 } 142 g_SvcPresentFBO.pQueueTail = pCmd; 143 144 RTCritSectLeave(&g_SvcPresentFBO.hQueueLock); 145 146 RTSemEventSignal(g_SvcPresentFBO.hEventProcess); 147 /* 148 HRESULT rc; 149 ComPtr<IDisplay> pDisplay; 150 151 CHECK_ERROR(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam())); 152 CHECK_ERROR(pDisplay, DrawToScreen(screenId, (BYTE*)data, x, y, w, h)); 153 */ 154 } 155 156 static DECLCALLBACK(int) svcPresentFBOWorkerThreadProc(RTTHREAD ThreadSelf, void *pvUser) 157 { 158 int rc = VINF_SUCCESS; 159 PCRVBOXSVCPRESENTFBOCMD_t pCmd; 160 161 Log(("SHARED_CROPENGL svcPresentFBOWorkerThreadProc started\n")); 162 163 for (;;) 164 { 165 rc = RTSemEventWait(g_SvcPresentFBO.hEventProcess, RT_INDEFINITE_WAIT); 166 AssertRCReturn(rc, rc); 167 168 if (g_SvcPresentFBO.bShutdownWorker) 169 { 170 break; 171 } 172 173 rc = RTCritSectEnter(&g_SvcPresentFBO.hQueueLock); 174 AssertRCReturn(rc, rc); 175 176 pCmd = g_SvcPresentFBO.pQueueHead; 177 while (pCmd) 178 { 179 ComPtr<IDisplay> pDisplay; 180 181 /*remove from queue*/ 182 g_SvcPresentFBO.pQueueHead = pCmd->pNext; 183 if (!g_SvcPresentFBO.pQueueHead) 184 { 185 g_SvcPresentFBO.pQueueTail = NULL; 186 } 187 188 CHECK_ERROR_RET(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()), rc); 189 190 RTCritSectLeave(&g_SvcPresentFBO.hQueueLock); 191 192 CHECK_ERROR_RET(pDisplay, DrawToScreen(pCmd->screenId, (BYTE*)pCmd->pData, pCmd->x, pCmd->y, pCmd->w, pCmd->h), rc); 193 194 crFree(pCmd->pData); 195 RTMemFree(pCmd); 196 197 rc = RTCritSectEnter(&g_SvcPresentFBO.hQueueLock); 198 AssertRCReturn(rc, rc); 199 pCmd = g_SvcPresentFBO.pQueueHead; 200 } 201 202 RTCritSectLeave(&g_SvcPresentFBO.hQueueLock); 203 } 204 205 Log(("SHARED_CROPENGL svcPresentFBOWorkerThreadProc finished\n")); 206 207 return rc; 208 } 209 210 static int svcPresentFBOInit(void) 211 { 212 int rc = VINF_SUCCESS; 213 214 g_SvcPresentFBO.pQueueHead = NULL; 215 g_SvcPresentFBO.pQueueTail = NULL; 216 g_SvcPresentFBO.bShutdownWorker = false; 217 218 rc = RTCritSectInit(&g_SvcPresentFBO.hQueueLock); 219 AssertRCReturn(rc, rc); 220 221 rc = RTSemEventCreate(&g_SvcPresentFBO.hEventProcess); 222 AssertRCReturn(rc, rc); 223 224 rc = RTThreadCreate(&g_SvcPresentFBO.hWorkerThread, svcPresentFBOWorkerThreadProc, NULL, 0, 225 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "OpenGLWorker"); 226 AssertRCReturn(rc, rc); 227 228 crVBoxServerSetPresentFBOCB(svcPresentFBO); 229 230 return rc; 231 } 232 233 static int svcPresentFBOTearDown(void) 234 { 235 int rc = VINF_SUCCESS; 236 PCRVBOXSVCPRESENTFBOCMD_t pQueue, pTmp; 237 238 ASMAtomicWriteBool(&g_SvcPresentFBO.bShutdownWorker, true); 239 RTSemEventSignal(g_SvcPresentFBO.hEventProcess); 240 rc = RTThreadWait(g_SvcPresentFBO.hWorkerThread, 5000, NULL); 241 AssertRCReturn(rc, rc); 242 243 RTCritSectDelete(&g_SvcPresentFBO.hQueueLock); 244 RTSemEventDestroy(g_SvcPresentFBO.hEventProcess); 245 246 pQueue = g_SvcPresentFBO.pQueueHead; 247 while (pQueue) 248 { 249 pTmp = pQueue->pNext; 250 crFree(pQueue->pData); 251 RTMemFree(pQueue); 252 pQueue = pTmp; 253 } 254 g_SvcPresentFBO.pQueueHead = NULL; 255 g_SvcPresentFBO.pQueueTail = NULL; 256 257 return rc; 258 } 259 85 260 static DECLCALLBACK(int) svcUnload (void *) 86 261 { … … 90 265 91 266 crVBoxServerTearDown(); 267 268 svcPresentFBOTearDown(); 92 269 93 270 return rc; … … 303 480 shown = 1; 304 481 } 305 }306 307 static DECLCALLBACK(void) svcPresentFBO(void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h)308 {309 #if 0310 ComPtr<IDisplay> pDisplay;311 BYTE *data;312 int i,j;313 CHECK_ERROR(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()));314 315 data = (BYTE*) RTMemTmpAllocZ(100*100*4);316 317 for (i=0; i<100; i+=2)318 {319 for (j=0; j<100; ++j)320 {321 *(data+i*100*4+j*4+0) = 0xFF;322 *(data+i*100*4+j*4+1) = 0xFF;323 *(data+i*100*4+j*4+2) = 0xFF;324 *(data+i*100*4+j*4+3) = 0xFF;325 }326 }327 328 CHECK_ERROR(pDisplay, DrawToScreen(screenId, data, 0, 0, 100, 100));329 330 RTMemTmpFree(data);331 #endif332 HRESULT rc;333 ComPtr<IDisplay> pDisplay;334 335 CHECK_ERROR(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()));336 CHECK_ERROR(pDisplay, DrawToScreen(screenId, (BYTE*)data, x, y, w, h));337 482 } 338 483 … … 1258 1403 return VERR_NOT_SUPPORTED; 1259 1404 1260 crVBoxServerSetPresentFBOCB(svcPresentFBO);1405 rc = svcPresentFBOInit(); 1261 1406 } 1262 1407 } -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c
r34270 r35770 337 337 if (crServerIntersectScreen(mural, i, &rect)) 338 338 { 339 tmppixels = crAlloc(4*(rect.x2-rect.x1)*(rect.y2-rect.y1));340 if (!tmppixels)341 {342 crWarning("Out of memory in crServerPresentFBO");343 crFree(pixels);344 return;345 }346 347 339 /* rect in window relative coords */ 348 340 crServerTransformRect(&rectwr, &rect, -mural->gX, -mural->gY); … … 350 342 if (!mural->pVisibleRects) 351 343 { 344 tmppixels = crAlloc(4*(rect.x2-rect.x1)*(rect.y2-rect.y1)); 345 if (!tmppixels) 346 { 347 crWarning("Out of memory in crServerPresentFBO"); 348 crFree(pixels); 349 return; 350 } 351 352 352 crServerCopySubImage(tmppixels, pixels, &rectwr, mural->fboWidth, mural->fboHeight); 353 /*Note: pfnPresentFBO would free tmppixels*/ 353 354 cr_server.pfnPresentFBO(tmppixels, i, rect.x1-cr_server.screen[i].x, rect.y1-cr_server.screen[i].y, rect.x2-rect.x1, rect.y2-rect.y1); 354 355 } … … 359 360 if (crServerIntersectRect(&rectwr, (CRrecti*) &mural->pVisibleRects[4*j], §r)) 360 361 { 362 tmppixels = crAlloc(4*(sectr.x2-sectr.x1)*(sectr.y2-sectr.y1)); 363 if (!tmppixels) 364 { 365 crWarning("Out of memory in crServerPresentFBO"); 366 crFree(pixels); 367 return; 368 } 369 361 370 crServerCopySubImage(tmppixels, pixels, §r, mural->fboWidth, mural->fboHeight); 371 /*Note: pfnPresentFBO would free tmppixels*/ 362 372 cr_server.pfnPresentFBO(tmppixels, i, 363 373 sectr.x1+mural->gX-cr_server.screen[i].x, … … 367 377 } 368 378 } 369 370 crFree(tmppixels);371 379 } 372 380 }
Note:
See TracChangeset
for help on using the changeset viewer.