VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp@ 50098

Last change on this file since 50098 was 50095, checked in by vboxsync, 11 years ago

crOpenGL: presentation infrastructure rework (still work in progress)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.6 KB
Line 
1/* $Id: server_muralfbo.cpp 50095 2014-01-17 16:34:07Z vboxsync $ */
2
3/** @file
4 * VBox crOpenGL: Window to FBO redirect support.
5 */
6
7/*
8 * Copyright (C) 2010-2013 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "server.h"
20#include "cr_string.h"
21#include "cr_mem.h"
22#include "cr_vreg.h"
23#include "render/renderspu.h"
24
25static void crServerRedirMuralFbSync(CRMuralInfo *mural);
26
27void crServerCheckMuralGeometry(CRMuralInfo *mural)
28{
29 if (!mural->CreateInfo.externalID)
30 return;
31
32 CRASSERT(mural->spuWindow);
33 CRASSERT(mural->spuWindow != CR_RENDER_DEFAULT_WINDOW_ID);
34
35 if (!mural->width || !mural->height
36 || mural->fboWidth != mural->width
37 || mural->fboHeight != mural->height)
38 {
39 crServerRedirMuralFbClear(mural);
40 crServerRedirMuralFBO(mural, false);
41 crServerDeleteMuralFBO(mural);
42 }
43
44 if (!mural->width || !mural->height)
45 return;
46
47 crServerRedirMuralFBO(mural, true);
48 crServerRedirMuralFbSync(mural);
49}
50
51GLboolean crServerSupportRedirMuralFBO(void)
52{
53 static GLboolean fInited = GL_FALSE;
54 static GLboolean fSupported = GL_FALSE;
55 if (!fInited)
56 {
57 const GLubyte* pExt = cr_server.head_spu->dispatch_table.GetString(GL_REAL_EXTENSIONS);
58
59 fSupported = ( NULL!=crStrstr((const char*)pExt, "GL_ARB_framebuffer_object")
60 || NULL!=crStrstr((const char*)pExt, "GL_EXT_framebuffer_object"))
61 && NULL!=crStrstr((const char*)pExt, "GL_ARB_texture_non_power_of_two");
62 fInited = GL_TRUE;
63 }
64 return fSupported;
65}
66
67static void crServerCreateMuralFBO(CRMuralInfo *mural);
68
69void crServerRedirMuralFbClear(CRMuralInfo *mural)
70{
71 uint32_t i;
72 for (i = 0; i < mural->cUsedFBDatas; ++i)
73 {
74 CR_FBDATA *pData = mural->apUsedFBDatas[i];
75 int rc = CrFbUpdateBegin(pData->hFb);
76 if (RT_SUCCESS(rc))
77 {
78 CrFbEntryRegionsSet(pData->hFb, pData->hFbEntry, NULL, 0, NULL, false);
79 CrFbUpdateEnd(pData->hFb);
80 }
81 else
82 WARN(("CrFbUpdateBegin failed rc %d", rc));
83 }
84 mural->cUsedFBDatas = 0;
85
86 for (i = 0; i < cr_server.screenCount; ++i)
87 {
88 GLuint j;
89 CR_FBDATA *pData = &mural->aFBDatas[i];
90 if (!pData->hFb)
91 continue;
92
93 CrFbEntryRelease(pData->hFb, pData->hFbEntry);
94 pData->hFbEntry = NULL;
95
96 for (j = 0; j < mural->cBuffers; ++j)
97 {
98 CrTdRelease(pData->apTexDatas[j]);
99 pData->apTexDatas[j] = NULL;
100 }
101
102 pData->hFb = NULL;
103 }
104}
105
106static int crServerRedirMuralDbSyncFb(CRMuralInfo *mural, HCR_FRAMEBUFFER hFb, CR_FBDATA **ppData)
107{
108 CR_FBDATA *pData;
109 const struct VBVAINFOSCREEN* pScreenInfo = CrFbGetScreenInfo(hFb);
110 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(hFb);
111 RTRECT FbRect = *CrVrScrCompositorRectGet(pCompositor);
112 RTRECT DefaultRegionsRect;
113 const RTRECT * pRegions;
114 uint32_t cRegions;
115 RTPOINT Pos;
116 RTRECT MuralRect;
117 int rc;
118
119 CRASSERT(mural->fRedirected);
120
121 *ppData = NULL;
122
123 if (!mural->bVisible)
124 return VINF_SUCCESS;
125
126 MuralRect.xLeft = mural->gX;
127 MuralRect.yTop = mural->gY;
128 MuralRect.xRight = MuralRect.xLeft + mural->width;
129 MuralRect.yBottom = MuralRect.yTop + mural->height;
130
131 Pos.x = mural->gX - pScreenInfo->i32OriginX;
132 Pos.y = mural->gY - pScreenInfo->i32OriginY;
133
134 VBoxRectTranslate(&FbRect, pScreenInfo->i32OriginX, pScreenInfo->i32OriginY);
135
136 VBoxRectIntersect(&FbRect, &MuralRect);
137
138 if (VBoxRectIsZero(&FbRect))
139 return VINF_SUCCESS;
140
141 if (mural->bReceivedRects)
142 {
143 pRegions = (const RTRECT*)mural->pVisibleRects;
144 cRegions = mural->cVisibleRects;
145 }
146 else
147 {
148 DefaultRegionsRect.xLeft = 0;
149 DefaultRegionsRect.yTop = 0;
150 DefaultRegionsRect.xRight = mural->width;
151 DefaultRegionsRect.yBottom = mural->height;
152 pRegions = &DefaultRegionsRect;
153 cRegions = 1;
154 }
155
156 if (!cRegions)
157 return VINF_SUCCESS;
158
159 pData = &mural->aFBDatas[pScreenInfo->u32ViewIndex];
160
161 if (!pData->hFb)
162 {
163 pData->hFb = hFb;
164
165 for (uint32_t i = 0; i < mural->cBuffers; ++i)
166 {
167 VBOXVR_TEXTURE Tex;
168 int rc;
169 Tex.width = mural->width;
170 Tex.height = mural->height;
171 Tex.hwid = mural->aidColorTexs[i];
172 Tex.target = GL_TEXTURE_2D;
173
174 pData->apTexDatas[i] = CrFbTexDataCreate(&Tex);
175 }
176
177 rc = CrFbEntryCreateForTexData(hFb, pData->apTexDatas[CR_SERVER_FBO_FB_IDX(mural)], 0, &pData->hFbEntry);
178 if (!RT_SUCCESS(rc))
179 {
180 WARN(("CrFbEntryCreateForTexData failed rc %d", rc));
181 }
182 }
183 else
184 {
185 CRASSERT(pData->hFb == hFb);
186 }
187
188 rc = CrFbUpdateBegin(hFb);
189 if (!RT_SUCCESS(rc))
190 {
191 WARN(("CrFbUpdateBegin failed rc %d", rc));
192 return rc;
193 }
194
195 rc = CrFbEntryRegionsSet(hFb, pData->hFbEntry, &Pos, cRegions, pRegions, true);
196 if (!RT_SUCCESS(rc))
197 {
198 WARN(("CrFbEntryRegionsSet failed rc %d", rc));
199 }
200
201 CrFbUpdateEnd(hFb);
202
203 const struct VBOXVR_SCR_COMPOSITOR_ENTRY* pCEntry = CrFbEntryGetCompositorEntry(pData->hFbEntry);
204 if (CrVrScrCompositorEntryIsUsed(pCEntry))
205 *ppData = pData;
206
207 return rc;
208}
209
210static void crServerRedirMuralFbSync(CRMuralInfo *mural)
211{
212 uint32_t i;
213 uint32_t cUsedFBs = 0;
214 HCR_FRAMEBUFFER ahUsedFbs[CR_MAX_GUEST_MONITORS];
215 HCR_FRAMEBUFFER hFb;
216
217 for (i = 0; i < mural->cUsedFBDatas; ++i)
218 {
219 CR_FBDATA *pData = mural->apUsedFBDatas[i];
220 int rc = CrFbUpdateBegin(pData->hFb);
221 if (RT_SUCCESS(rc))
222 {
223 ahUsedFbs[cUsedFBs] = pData->hFb;
224 CrFbEntryRegionsSet(pData->hFb, pData->hFbEntry, NULL, 0, NULL, false);
225 ++cUsedFBs;
226 }
227 else
228 WARN(("CrFbUpdateBegin failed rc %d", rc));
229 }
230 mural->cUsedFBDatas = 0;
231
232 if (!mural->width
233 || !mural->height
234 || !mural->bVisible
235 )
236 goto end;
237
238 CRASSERT(mural->fRedirected);
239
240 for (hFb = CrPMgrFbGetFirstEnabled();
241 hFb;
242 hFb = CrPMgrFbGetNextEnabled(hFb))
243 {
244 CR_FBDATA *pData = NULL;
245 int rc = crServerRedirMuralDbSyncFb(mural, hFb, &pData);
246 if (!RT_SUCCESS(rc))
247 {
248 WARN(("crServerRedirMuralDbSyncFb failed %d", rc));
249 continue;
250 }
251
252 if (!pData)
253 continue;
254
255 mural->apUsedFBDatas[mural->cUsedFBDatas] = pData;
256 ++mural->cUsedFBDatas;
257 }
258
259end:
260
261 for (i = 0; i < cUsedFBs; ++i)
262 {
263 CrFbUpdateEnd(ahUsedFbs[i]);
264 }
265}
266
267static void crVBoxServerMuralFbCleanCB(unsigned long key, void *data1, void *data2)
268{
269 CRMuralInfo *pMI = (CRMuralInfo*) data1;
270 HCR_FRAMEBUFFER hFb = (HCR_FRAMEBUFFER)data2;
271 uint32_t i;
272 for (i = 0; i < pMI->cUsedFBDatas; ++i)
273 {
274 CR_FBDATA *pData = pMI->apUsedFBDatas[i];
275 if (hFb != pData->hFb)
276 continue;
277
278 CrFbEntryRegionsSet(pData->hFb, pData->hFbEntry, NULL, 0, NULL, false);
279 break;
280 }
281}
282
283static void crVBoxServerMuralFbSetCB(unsigned long key, void *data1, void *data2)
284{
285 CRMuralInfo *pMI = (CRMuralInfo*) data1;
286 HCR_FRAMEBUFFER hFb = (HCR_FRAMEBUFFER)data2;
287 uint32_t i;
288 CR_FBDATA *pData = NULL;
289 bool fFbWasUsed = false;
290
291 Assert(hFb);
292
293 if (!pMI->fRedirected)
294 {
295 Assert(!pMI->cUsedFBDatas);
296 return;
297 }
298
299 for (i = 0; i < pMI->cUsedFBDatas; ++i)
300 {
301 CR_FBDATA *pData = pMI->apUsedFBDatas[i];
302 if (hFb != pData->hFb)
303 continue;
304
305 fFbWasUsed = true;
306 break;
307 }
308
309 if (CrFbIsEnabled(hFb))
310 {
311 int rc = crServerRedirMuralDbSyncFb(pMI, hFb, &pData);
312 if (!RT_SUCCESS(rc))
313 {
314 WARN(("crServerRedirMuralDbSyncFb failed %d", rc));
315 pData = NULL;
316 }
317 }
318
319 if (pData)
320 {
321 if (!fFbWasUsed)
322 {
323 uint32_t idScreen = CrFbGetScreenInfo(hFb)->u32ViewIndex;
324 for (i = 0; i < pMI->cUsedFBDatas; ++i)
325 {
326 CR_FBDATA *pData = pMI->apUsedFBDatas[i];
327 uint32_t idCurScreen = CrFbGetScreenInfo(pData->hFb)->u32ViewIndex;
328 if (idCurScreen > idScreen)
329 break;
330
331 Assert(idCurScreen != idScreen);
332 }
333
334 for (int j = pMI->cUsedFBDatas; j > i; --j)
335 {
336 pMI->apUsedFBDatas[j] = pMI->apUsedFBDatas[j-1];
337 }
338
339 pMI->apUsedFBDatas[i] = pData;
340 ++pMI->cUsedFBDatas;
341 }
342 /* else - nothing to do */
343 }
344 else
345 {
346 if (fFbWasUsed)
347 {
348 for (int j = i; j < pMI->cUsedFBDatas - 1; ++j)
349 {
350 pMI->apUsedFBDatas[j] = pMI->apUsedFBDatas[j+1];
351 }
352 --pMI->cUsedFBDatas;
353 }
354 /* else - nothing to do */
355 }
356}
357
358void crVBoxServerMuralFbResizeEnd(HCR_FRAMEBUFFER hFb)
359{
360 crHashtableWalk(cr_server.muralTable, crVBoxServerMuralFbSetCB, hFb);
361}
362
363void crVBoxServerMuralFbResizeBegin(HCR_FRAMEBUFFER hFb)
364{
365 crHashtableWalk(cr_server.muralTable, crVBoxServerMuralFbCleanCB, hFb);
366}
367
368DECLEXPORT(int) crVBoxServerNotifyResize(const struct VBVAINFOSCREEN *pScreen, void *pvVRAM)
369{
370 int rc;
371 HCR_FRAMEBUFFER hFb = CrPMgrFbGet(pScreen->u32ViewIndex);
372 if (!hFb)
373 {
374 WARN(("CrPMgrFbGet failed"));
375 return VERR_INVALID_PARAMETER;
376 }
377
378 rc = CrFbUpdateBegin(hFb);
379 if (!RT_SUCCESS(rc))
380 {
381 WARN(("CrFbUpdateBegin failed %d", rc));
382 return rc;
383 }
384
385 crVBoxServerMuralFbResizeBegin(hFb);
386
387 rc = CrFbResize(hFb, pScreen, pvVRAM);
388 if (!RT_SUCCESS(rc))
389 {
390 WARN(("CrFbResize failed %d", rc));
391 }
392
393 crVBoxServerMuralFbResizeEnd(hFb);
394
395 CrFbUpdateEnd(hFb);
396
397 CrPMgrNotifyResize(hFb);
398
399 return rc;
400}
401
402void crServerRedirMuralFBO(CRMuralInfo *mural, bool fEnabled)
403{
404 if (!mural->fRedirected == !fEnabled)
405 {
406 return;
407 }
408
409 if (!mural->CreateInfo.externalID)
410 {
411 WARN(("trying to change redir setting for internal mural %d", mural->spuWindow));
412 return;
413 }
414
415 if (fEnabled)
416 {
417 if (!crServerSupportRedirMuralFBO())
418 {
419 WARN(("FBO not supported, can't redirect window output"));
420 return;
421 }
422
423 if (mural->aidFBOs[0]==0)
424 {
425 crServerCreateMuralFBO(mural);
426 }
427
428 if (cr_server.curClient && cr_server.curClient->currentMural == mural)
429 {
430 if (!crStateGetCurrent()->framebufferobject.drawFB)
431 {
432 cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, CR_SERVER_FBO_FOR_IDX(mural, mural->iCurDrawBuffer));
433 }
434 if (!crStateGetCurrent()->framebufferobject.readFB)
435 {
436 cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, CR_SERVER_FBO_FOR_IDX(mural, mural->iCurReadBuffer));
437 }
438
439 crStateGetCurrent()->buffer.width = 0;
440 crStateGetCurrent()->buffer.height = 0;
441 }
442 }
443 else
444 {
445 if (cr_server.curClient && cr_server.curClient->currentMural == mural)
446 {
447 if (!crStateGetCurrent()->framebufferobject.drawFB)
448 {
449 cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
450 }
451 if (!crStateGetCurrent()->framebufferobject.readFB)
452 {
453 cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
454 }
455
456 crStateGetCurrent()->buffer.width = mural->width;
457 crStateGetCurrent()->buffer.height = mural->height;
458 }
459 }
460
461 mural->fRedirected = !!fEnabled;
462}
463
464static void crServerCreateMuralFBO(CRMuralInfo *mural)
465{
466 CRContext *ctx = crStateGetCurrent();
467 GLuint uid, i;
468 GLenum status;
469 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
470 CRContextInfo *pMuralContextInfo;
471
472 CRASSERT(mural->aidFBOs[0]==0);
473 CRASSERT(mural->aidFBOs[1]==0);
474
475 pMuralContextInfo = cr_server.currentCtxInfo;
476 if (!pMuralContextInfo)
477 {
478 /* happens on saved state load */
479 CRASSERT(cr_server.MainContextInfo.SpuContext);
480 pMuralContextInfo = &cr_server.MainContextInfo;
481 cr_server.head_spu->dispatch_table.MakeCurrent(mural->spuWindow, 0, cr_server.MainContextInfo.SpuContext);
482 }
483
484 if (pMuralContextInfo->CreateInfo.visualBits != mural->CreateInfo.visualBits)
485 {
486 WARN(("mural visual bits do not match with current context visual bits!"));
487 }
488
489 mural->cBuffers = 2;
490 mural->iBbBuffer = 0;
491 /*Color texture*/
492
493 if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
494 {
495 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
496 }
497
498 for (i = 0; i < mural->cBuffers; ++i)
499 {
500 gl->GenTextures(1, &mural->aidColorTexs[i]);
501 gl->BindTexture(GL_TEXTURE_2D, mural->aidColorTexs[i]);
502 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
503 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
504 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
505 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
506 gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mural->width, mural->height,
507 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
508 }
509
510 /*Depth&Stencil*/
511 gl->GenRenderbuffersEXT(1, &mural->idDepthStencilRB);
512 gl->BindRenderbufferEXT(GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);
513 gl->RenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT,
514 mural->width, mural->height);
515
516 /*FBO*/
517 for (i = 0; i < mural->cBuffers; ++i)
518 {
519 gl->GenFramebuffersEXT(1, &mural->aidFBOs[i]);
520 gl->BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mural->aidFBOs[i]);
521
522 gl->FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
523 GL_TEXTURE_2D, mural->aidColorTexs[i], 0);
524 gl->FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
525 GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);
526 gl->FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
527 GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);
528
529 status = gl->CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
530 if (status!=GL_FRAMEBUFFER_COMPLETE_EXT)
531 {
532 WARN(("FBO status(0x%x) isn't complete", status));
533 }
534 }
535
536 mural->iCurDrawBuffer = crServerMuralFBOIdxFromBufferName(mural, ctx->buffer.drawBuffer);
537 mural->iCurReadBuffer = crServerMuralFBOIdxFromBufferName(mural, ctx->buffer.readBuffer);
538
539 mural->fboWidth = mural->width;
540 mural->fboHeight = mural->height;
541
542 mural->iCurDrawBuffer = crServerMuralFBOIdxFromBufferName(mural, ctx->buffer.drawBuffer);
543 mural->iCurReadBuffer = crServerMuralFBOIdxFromBufferName(mural, ctx->buffer.readBuffer);
544
545 /*Restore gl state*/
546 uid = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid;
547 gl->BindTexture(GL_TEXTURE_2D, uid);
548
549 uid = ctx->framebufferobject.renderbuffer ? ctx->framebufferobject.renderbuffer->hwid:0;
550 gl->BindRenderbufferEXT(GL_RENDERBUFFER_EXT, uid);
551
552 uid = ctx->framebufferobject.drawFB ? ctx->framebufferobject.drawFB->hwid:0;
553 gl->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, uid);
554
555 uid = ctx->framebufferobject.readFB ? ctx->framebufferobject.readFB->hwid:0;
556 gl->BindFramebufferEXT(GL_READ_FRAMEBUFFER, uid);
557
558 if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
559 {
560 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ctx->bufferobject.unpackBuffer->hwid);
561 }
562
563 if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
564 {
565 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
566 }
567 else
568 {
569 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
570 }
571
572 CRASSERT(mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]);
573}
574
575void crServerDeleteMuralFBO(CRMuralInfo *mural)
576{
577 if (mural->aidFBOs[0]!=0)
578 {
579 GLuint i;
580 for (i = 0; i < mural->cBuffers; ++i)
581 {
582 cr_server.head_spu->dispatch_table.DeleteTextures(1, &mural->aidColorTexs[i]);
583 mural->aidColorTexs[i] = 0;
584 }
585
586 cr_server.head_spu->dispatch_table.DeleteRenderbuffersEXT(1, &mural->idDepthStencilRB);
587 mural->idDepthStencilRB = 0;
588
589 for (i = 0; i < mural->cBuffers; ++i)
590 {
591 cr_server.head_spu->dispatch_table.DeleteFramebuffersEXT(1, &mural->aidFBOs[i]);
592 mural->aidFBOs[i] = 0;
593 }
594 }
595
596 mural->cBuffers = 0;
597}
598
599#define MIN(a, b) ((a) < (b) ? (a) : (b))
600#define MAX(a, b) ((a) > (b) ? (a) : (b))
601
602static GLboolean crServerIntersectRect(CRrecti *a, CRrecti *b, CRrecti *rect)
603{
604 CRASSERT(a && b && rect);
605
606 rect->x1 = MAX(a->x1, b->x1);
607 rect->x2 = MIN(a->x2, b->x2);
608 rect->y1 = MAX(a->y1, b->y1);
609 rect->y2 = MIN(a->y2, b->y2);
610
611 return (rect->x2>rect->x1) && (rect->y2>rect->y1);
612}
613
614static void crServerCopySubImage(char *pDst, char* pSrc, CRrecti *pRect, int srcWidth, int srcHeight)
615{
616 int i;
617 int dstrowsize = 4*(pRect->x2-pRect->x1);
618 int srcrowsize = 4*srcWidth;
619 int height = pRect->y2-pRect->y1;
620
621 pSrc += 4*pRect->x1 + srcrowsize*(srcHeight-1-pRect->y1);
622
623 for (i=0; i<height; ++i)
624 {
625 crMemcpy(pDst, pSrc, dstrowsize);
626
627 pSrc -= srcrowsize;
628 pDst += dstrowsize;
629 }
630}
631
632DECLEXPORT(void) crServerVBoxCompositionSetEnableStateGlobal(GLboolean fEnable)
633{
634}
635
636void crServerPresentFBO(CRMuralInfo *mural)
637{
638 uint32_t i;
639 for (i = 0; i < mural->cUsedFBDatas; ++i)
640 {
641 CR_FBDATA *pData = mural->apUsedFBDatas[i];
642 int rc = CrFbUpdateBegin(pData->hFb);
643 if (RT_SUCCESS(rc))
644 {
645 CrFbEntryTexDataUpdate(pData->hFb, pData->hFbEntry, pData->apTexDatas[CR_SERVER_FBO_FB_IDX(mural)]);
646 CrFbUpdateEnd(pData->hFb);
647 }
648 else
649 WARN(("CrFbUpdateBegin failed rc %d", rc));
650 }
651}
652
653GLboolean crServerIsRedirectedToFBO()
654{
655#ifdef DEBUG_misha
656 Assert(cr_server.curClient);
657 if (cr_server.curClient)
658 {
659 Assert(cr_server.curClient->currentMural == cr_server.currentMural);
660 Assert(cr_server.curClient->currentCtxInfo == cr_server.currentCtxInfo);
661 }
662#endif
663 return cr_server.curClient
664 && cr_server.curClient->currentMural
665 && cr_server.curClient->currentMural->fRedirected;
666}
667
668GLint crServerMuralFBOIdxFromBufferName(CRMuralInfo *mural, GLenum buffer)
669{
670 switch (buffer)
671 {
672 case GL_FRONT:
673 case GL_FRONT_LEFT:
674 case GL_FRONT_RIGHT:
675 return CR_SERVER_FBO_FB_IDX(mural);
676 case GL_BACK:
677 case GL_BACK_LEFT:
678 case GL_BACK_RIGHT:
679 return CR_SERVER_FBO_BB_IDX(mural);
680 case GL_NONE:
681 case GL_AUX0:
682 case GL_AUX1:
683 case GL_AUX2:
684 case GL_AUX3:
685 case GL_LEFT:
686 case GL_RIGHT:
687 case GL_FRONT_AND_BACK:
688 return -1;
689 default:
690 WARN(("crServerMuralFBOIdxFromBufferName: invalid buffer passed 0x%x", buffer));
691 return -2;
692 }
693}
694
695void crServerMuralFBOSwapBuffers(CRMuralInfo *mural)
696{
697 CRContext *ctx = crStateGetCurrent();
698 GLuint iOldCurDrawBuffer = mural->iCurDrawBuffer;
699 GLuint iOldCurReadBuffer = mural->iCurReadBuffer;
700 mural->iBbBuffer = ((mural->iBbBuffer + 1) % (mural->cBuffers));
701 if (mural->iCurDrawBuffer >= 0)
702 mural->iCurDrawBuffer = ((mural->iCurDrawBuffer + 1) % (mural->cBuffers));
703 if (mural->iCurReadBuffer >= 0)
704 mural->iCurReadBuffer = ((mural->iCurReadBuffer + 1) % (mural->cBuffers));
705 Assert(iOldCurDrawBuffer != mural->iCurDrawBuffer || mural->cBuffers == 1 || mural->iCurDrawBuffer < 0);
706 Assert(iOldCurReadBuffer != mural->iCurReadBuffer || mural->cBuffers == 1 || mural->iCurReadBuffer < 0);
707 if (!ctx->framebufferobject.drawFB && iOldCurDrawBuffer != mural->iCurDrawBuffer)
708 {
709 cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, CR_SERVER_FBO_FOR_IDX(mural, mural->iCurDrawBuffer));
710 }
711 if (!ctx->framebufferobject.readFB && iOldCurReadBuffer != mural->iCurReadBuffer)
712 {
713 cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, CR_SERVER_FBO_FOR_IDX(mural, mural->iCurReadBuffer));
714 }
715 Assert(mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]);
716}
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