VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp@ 43888

Last change on this file since 43888 was 43888, checked in by vboxsync, 13 years ago

crOpenGL: more new present mechanism

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.4 KB
Line 
1/* $Id: server_presenter.cpp 43888 2012-11-15 21:23:50Z vboxsync $ */
2
3/** @file
4 * Presenter API
5 */
6
7/*
8 * Copyright (C) 2012 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.215389.xyz. 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#include "cr_spu.h"
19#include "chromium.h"
20#include "cr_error.h"
21#include "cr_net.h"
22#include "cr_rand.h"
23#include "server_dispatch.h"
24#include "server.h"
25#include "cr_mem.h"
26#include "cr_string.h"
27#include <cr_vreg.h>
28
29#include <iprt/cdefs.h>
30#include <iprt/types.h>
31#include <iprt/asm.h>
32#include <iprt/mem.h>
33
34typedef DECLCALLBACK(int) FNCRDISPLAY_REGIONS_CHANGED(struct CR_PRESENTER *pPresenter);
35typedef FNCRDISPLAY_REGIONS_CHANGED *PFNCRDISPLAY_REGIONS_CHANGED;
36
37typedef DECLCALLBACK(int) FNCRDISPLAY_DRAW_ENTRY(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter);
38typedef FNCRDISPLAY_DRAW_ENTRY *PFNCRDISPLAY_DRAW_ENTRY;
39
40typedef DECLCALLBACK(int) FNCRDISPLAY_DRAW_TEXTURE(struct CR_PRESENTER *pPresenter, PCR_BLITTER pBlitter,
41 CR_BLITTER_TEXTURE *pTexture, const RTRECT *paSrcRects, const RTRECT *paDstRects, uint32_t cRects);
42typedef FNCRDISPLAY_DRAW_TEXTURE *PFNCRDISPLAY_DRAW_TEXTURE;
43
44
45#define CR_DISPLAY_RECTS_UNDEFINED UINT32_MAX
46
47
48#define CR_PRESENTER_ENTRY_FROM_ENTRY(_p) ((PCR_PRESENTER_ENTRY)(((uint8_t*)(_p)) - RT_OFFSETOF(CR_PRESENTER_ENTRY, Ce)))
49#define CR_PRESENTER_FROM_COMPOSITOR(_p) ((PCR_PRESENTER)(((uint8_t*)(_p)) - RT_OFFSETOF(CR_PRESENTER, Compositor)))
50
51
52static int crPtRectsAssignBuffer(PCR_PRESENTER pPresenter, uint32_t cRects)
53{
54 Assert(cRects);
55
56 if (pPresenter->cRectsBuffer >= cRects)
57 {
58 pPresenter->cRects = cRects;
59 return VINF_SUCCESS;
60 }
61
62 if (pPresenter->cRectsBuffer)
63 {
64 Assert(pPresenter->paSrcRects);
65 RTMemFree(pPresenter->paSrcRects);
66 Assert(pPresenter->paDstRects);
67 RTMemFree(pPresenter->paDstRects);
68 }
69
70 pPresenter->paSrcRects = (PRTRECT)RTMemAlloc(sizeof (*pPresenter->paSrcRects) * cRects);
71 if (pPresenter->paSrcRects)
72 {
73 pPresenter->paDstRects = (PRTRECT)RTMemAlloc(sizeof (*pPresenter->paDstRects) * cRects);
74 if (pPresenter->paDstRects)
75 {
76 pPresenter->cRects = cRects;
77 pPresenter->cRectsBuffer = cRects;
78 return VINF_SUCCESS;
79 }
80 else
81 {
82 crWarning("RTMemAlloc failed!");
83 RTMemFree(pPresenter->paSrcRects);
84 pPresenter->paSrcRects = NULL;
85 }
86 }
87 else
88 {
89 crWarning("RTMemAlloc failed!");
90 pPresenter->paDstRects = NULL;
91 }
92
93 pPresenter->cRects = CR_DISPLAY_RECTS_UNDEFINED;
94 pPresenter->cRectsBuffer = 0;
95
96 return VERR_NO_MEMORY;
97}
98
99static void crPtRectsInvalidate(PCR_PRESENTER pPresenter)
100{
101 pPresenter->cRects = CR_DISPLAY_RECTS_UNDEFINED;
102}
103
104static DECLCALLBACK(bool) crPtRectsCounterCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, void *pvVisitor)
105{
106 uint32_t* pCounter = (uint32_t*)pvVisitor;
107 Assert(VBoxVrListRectsCount(&pEntry->Vr));
108 *pCounter += VBoxVrListRectsCount(&pEntry->Vr);
109 return true;
110}
111
112typedef struct CR_PRESENTOR_RECTS_ASSIGNER
113{
114 PRTRECT paSrcRects;
115 PRTRECT paDstRects;
116 uint32_t cRects;
117} CR_PRESENTOR_RECTS_ASSIGNER, *PCR_PRESENTOR_RECTS_ASSIGNER;
118
119static DECLCALLBACK(bool) crPtRectsAssignerCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
120{
121 PCR_PRESENTOR_RECTS_ASSIGNER pData = (PCR_PRESENTOR_RECTS_ASSIGNER)pvVisitor;
122 PCR_PRESENTER pPresenter = CR_PRESENTER_FROM_COMPOSITOR(pCompositor);
123 PCR_PRESENTER_ENTRY pEntry = CR_PRESENTER_ENTRY_FROM_ENTRY(pCEntry);
124 pEntry->paSrcRects = pData->paSrcRects;
125 pEntry->paDstRects = pData->paDstRects;
126 uint32_t cRects = VBoxVrListRectsCount(&pCEntry->Vr);
127 Assert(cRects);
128 Assert(cRects >= pData->cRects);
129 int rc = VBoxVrListRectsGet(&pCEntry->Vr, cRects, pEntry->paDstRects);
130 AssertRC(rc);
131 if (pPresenter->StretchX >= 1. && pPresenter->StretchY >= 1. /* <- stretching can not zero some rects */
132 && !pEntry->Pos.x && !pEntry->Pos.y)
133 {
134 memcpy(pEntry->paSrcRects, pEntry->paDstRects, cRects * sizeof (*pEntry->paSrcRects));
135 }
136 else
137 {
138 for (uint32_t i = 0; i < cRects; ++i)
139 {
140 pEntry->paSrcRects[i].xLeft = (pEntry->paDstRects[i].xLeft - pEntry->Pos.x) * pPresenter->StretchX;
141 pEntry->paSrcRects[i].yTop = (pEntry->paDstRects[i].yTop - pEntry->Pos.y) * pPresenter->StretchY;
142 pEntry->paSrcRects[i].xRight = (pEntry->paDstRects[i].xRight - pEntry->Pos.x) * pPresenter->StretchX;
143 pEntry->paSrcRects[i].yBottom = (pEntry->paDstRects[i].yBottom - pEntry->Pos.y) * pPresenter->StretchY;
144 }
145
146 bool canZeroX = (pPresenter->StretchX < 1);
147 bool canZeroY = (pPresenter->StretchY < 1);
148 if (canZeroX && canZeroY)
149 {
150 /* filter out zero rectangles*/
151 uint32_t iOrig, iNew;
152 for (iOrig = 0, iNew = 0; iOrig < cRects; ++iOrig)
153 {
154 PRTRECT pOrigRect = &pEntry->paSrcRects[iOrig];
155 if (pOrigRect->xLeft == pOrigRect->xRight
156 || pOrigRect->yTop == pOrigRect->yBottom)
157 continue;
158
159 if (iNew != iOrig)
160 {
161 PRTRECT pNewRect = &pEntry->paSrcRects[iNew];
162 *pNewRect = *pOrigRect;
163 }
164
165 ++iNew;
166 }
167
168 Assert(iNew <= iOrig);
169
170 uint32_t cDiff = iOrig - iNew;
171
172 if (cDiff)
173 {
174 pPresenter->cRects -= cDiff;
175 cRects -= cDiff;
176 }
177 }
178 }
179
180 pEntry->cRects = cRects;
181 pData->paDstRects += cRects;
182 pData->paSrcRects += cRects;
183 pData->cRects -= cRects;
184 return true;
185}
186
187static int crPtRectsCheckInit(PCR_PRESENTER pPresenter)
188{
189 if (pPresenter->cRects != CR_DISPLAY_RECTS_UNDEFINED)
190 return VINF_SUCCESS;
191
192 uint32_t cRects = 0;
193 VBoxVrCompositorVisit(&pPresenter->Compositor, crPtRectsCounterCb, &cRects);
194
195 if (!cRects)
196 {
197 pPresenter->cRects = 0;
198 return VINF_SUCCESS;
199 }
200
201 int rc = crPtRectsAssignBuffer(pPresenter, cRects);
202 if (!RT_SUCCESS(rc))
203 return rc;
204
205 CR_PRESENTOR_RECTS_ASSIGNER AssignerData;
206 AssignerData.paSrcRects = pPresenter->paSrcRects;
207 AssignerData.paDstRects = pPresenter->paDstRects;
208 AssignerData.cRects = pPresenter->cRects;
209 VBoxVrCompositorVisit(&pPresenter->Compositor, crPtRectsAssignerCb, &AssignerData);
210 Assert(!AssignerData.cRects);
211 return VINF_SUCCESS;
212}
213
214DECLCALLBACK(int) CrPtCbDrawEntrySingle(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter)
215{
216 int rc = crPtRectsCheckInit(pPresenter);
217 if (!RT_SUCCESS(rc))
218 {
219 crWarning("crPtRectsCheckInit failed, rc %d", rc);
220 return rc;
221 }
222
223 Assert(VBoxVrListRectsCount(&pEntry->Ce.Vr));
224
225 if (!pEntry->cRects)
226 return VINF_SUCCESS;
227
228 rc = pPresenter->pfnDrawTexture(pPresenter, pBlitter, &pEntry->Texture, pEntry->paSrcRects, pEntry->paDstRects, pEntry->cRects);
229 if (!RT_SUCCESS(rc))
230 {
231 crWarning("pfnDrawTexture failed, rc %d", rc);
232 return rc;
233 }
234
235 return VINF_SUCCESS;
236}
237
238static DECLCALLBACK(bool) crPtDrawEntryAllCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
239{
240 struct CR_PRESENTER *pPresenter = CR_PRESENTER_FROM_COMPOSITOR(pCompositor);
241 struct CR_PRESENTER_ENTRY *pEntry = CR_PRESENTER_ENTRY_FROM_ENTRY(pCEntry);
242 PCR_BLITTER pBlitter = (PCR_BLITTER)pvVisitor;
243 int rc = CrPtCbDrawEntrySingle(pPresenter, pEntry, pBlitter);
244 if (!RT_SUCCESS(rc))
245 {
246 crWarning("CrPtCbDrawEntrySingle failed, rc %d", rc);
247 }
248 return true;
249}
250
251DECLCALLBACK(int) CrPtCbDrawEntryAll(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter)
252{
253 int rc = crPtRectsCheckInit(pPresenter);
254 if (!RT_SUCCESS(rc))
255 {
256 crWarning("crPtRectsCheckInit failed, rc %d", rc);
257 return rc;
258 }
259
260 VBoxVrCompositorVisit(&pPresenter->Compositor, crPtDrawEntryAllCb, pPresenter);
261
262 return VINF_SUCCESS;
263}
264
265static int crPtEntryRegionsAdd(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
266{
267 uint32_t fChangedFlags = 0;
268 int rc = VBoxVrCompositorEntryRegionsAdd(&pPresenter->Compositor, &pEntry->Ce, cRegions, paRegions, &fChangedFlags);
269 if (!RT_SUCCESS(rc))
270 {
271 crWarning("VBoxVrCompositorEntryRegionsAdd failed, rc %d", rc);
272 return rc;
273 }
274
275 if (fChangedFlags & VBOXVR_COMPOSITOR_CF_COMPOSITED_REGIONS_CHANGED)
276 {
277 crPtRectsInvalidate(pPresenter);
278 rc = pPresenter->pfnRegionsChanged(pPresenter);
279 if (!RT_SUCCESS(rc))
280 {
281 crWarning("pfnRegionsChanged failed, rc %d", rc);
282 return rc;
283 }
284 }
285
286 if (pfChanged)
287 *pfChanged = !!fChangedFlags;
288 return VINF_SUCCESS;
289}
290
291static void crPtEntryPositionSet(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, const RTPOINT *pPos)
292{
293 if (pEntry && pEntry->Pos.x != pPos->x || pEntry->Pos.y != pPos->y)
294 {
295 VBoxVrCompositorEntryRemove(&pPresenter->Compositor, &pEntry->Ce);
296 crPtRectsInvalidate(pPresenter);
297 pEntry->Pos = *pPos;
298 }
299}
300
301int CrPtEntryPresent(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, PCR_BLITTER pBlitter)
302{
303 crPtEntryPositionSet(pPresenter, pEntry, pPos);
304
305 int rc = crPtEntryRegionsAdd(pPresenter, pEntry, cRegions, paRegions, NULL);
306 if (!RT_SUCCESS(rc))
307 {
308 crWarning("crPtEntryRegionsAdd failed, rc %d", rc);
309 return rc;
310 }
311
312 if (!pEntry)
313 return VINF_SUCCESS;
314
315 rc = CrBltEnter(pBlitter, cr_server.currentCtxInfo, cr_server.currentMural);
316 if (!RT_SUCCESS(rc))
317 {
318 crWarning("CrBltEnter failed, rc %d", rc);
319 return rc;
320 }
321
322 rc = pPresenter->pfnDrawEntry(pPresenter, pEntry, pBlitter);
323
324 CrBltLeave(pBlitter);
325
326 if (!RT_SUCCESS(rc))
327 {
328 crWarning("pfnDrawEntry failed, rc %d", rc);
329 return rc;
330 }
331 return VINF_SUCCESS;
332}
333
334int CrPtEntryRemove(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry)
335{
336 if (!VBoxVrCompositorEntryRemove(&pPresenter->Compositor, &pEntry->Ce))
337 return VINF_SUCCESS;
338
339 crPtRectsInvalidate(pPresenter);
340 int rc = pPresenter->pfnRegionsChanged(pPresenter);
341 if (!RT_SUCCESS(rc))
342 {
343 crWarning("pfnRegionsChanged failed, rc %d", rc);
344 return rc;
345 }
346 return VINF_SUCCESS;
347}
348
349int CrPtInit(PCR_PRESENTER pPresenter, PFNCRDISPLAY_REGIONS_CHANGED pfnRegionsChanged, PFNCRDISPLAY_DRAW_ENTRY pfnDrawEntry, PFNCRDISPLAY_DRAW_TEXTURE pfnDrawTexture)
350{
351 memset(pPresenter, 0, sizeof (*pPresenter));
352 VBoxVrCompositorInit(&pPresenter->Compositor, NULL);
353 pPresenter->StretchX = 1.0;
354 pPresenter->StretchY = 1.0;
355 pPresenter->pfnRegionsChanged = pfnRegionsChanged;
356 pPresenter->pfnDrawEntry = pfnDrawEntry;
357 pPresenter->pfnDrawTexture = pfnDrawTexture;
358 return VINF_SUCCESS;
359}
360
361void CrPtTerm(PCR_PRESENTER pPresenter)
362{
363 VBoxVrCompositorTerm(&pPresenter->Compositor);
364 if (pPresenter->paDstRects)
365 RTMemFree(pPresenter->paDstRects);
366 if (pPresenter->paSrcRects)
367 RTMemFree(pPresenter->paSrcRects);
368}
369
370void CrPtSetStretching(PCR_PRESENTER pPresenter, float StretchX, float StretchY)
371{
372 pPresenter->StretchX = StretchX;
373 pPresenter->StretchY = StretchY;
374 crPtRectsInvalidate(pPresenter);
375}
376
377int CrPtGetRegions(PCR_PRESENTER pPresenter, uint32_t *pcRegions, const RTRECT **ppaRegions)
378{
379 int rc = crPtRectsCheckInit(pPresenter);
380 if (!RT_SUCCESS(rc))
381 {
382 crWarning("crPtRectsCheckInit failed, rc %d", rc);
383 return rc;
384 }
385
386 Assert(pPresenter->cRects != CR_DISPLAY_RECTS_UNDEFINED);
387
388 *pcRegions = pPresenter->cRects;
389 *ppaRegions = pPresenter->paDstRects;
390 return VINF_SUCCESS;
391}
392
393/* DISPLAY */
394#define CR_DISPLAY_FROM_PRESENTER(_p) ((PCR_DISPLAY)(((uint8_t*)(_p)) - RT_OFFSETOF(CR_DISPLAY, Presenter)))
395
396static DECLCALLBACK(int) crDpCbRegionsChanged(struct CR_PRESENTER *pPresenter)
397{
398 uint32_t cRegions;
399 const RTRECT *paRegions;
400 int rc = CrPtGetRegions(pPresenter, &cRegions, &paRegions);
401 if (!RT_SUCCESS(rc))
402 {
403 crWarning("CrPtGetRegions failed, rc %d", rc);
404 return rc;
405 }
406
407 PCR_DISPLAY pDisplay = CR_DISPLAY_FROM_PRESENTER(pPresenter);
408
409 cr_server.head_spu->dispatch_table.WindowVisibleRegion(pDisplay->Mural.spuWindow, cRegions, (GLint*)paRegions);
410
411 if (pDisplay->Mural.pvOutputRedirectInstance)
412 {
413 /* @todo the code assumes that RTRECT == four GLInts. */
414 cr_server.outputRedirect.CRORVisibleRegion(pDisplay->Mural.pvOutputRedirectInstance,
415 cRegions, paRegions);
416 }
417
418 return VINF_SUCCESS;
419}
420
421static DECLCALLBACK(int) crDpCbDrawTextureWindow(struct CR_PRESENTER *pPresenter, PCR_BLITTER pBlitter,
422 CR_BLITTER_TEXTURE *pTexture, const RTRECT *paSrcRects, const RTRECT *paDstRects, uint32_t cRects)
423{
424 Assert(CrBltIsEntered(pBlitter));
425 CrBltBlitTexMural(pBlitter, pTexture, paSrcRects, paDstRects, cRects, 0);
426 return VINF_SUCCESS;
427}
428
429int CrDpInit(PCR_DISPLAY pDisplay)
430{
431 const GLint visBits = CR_RGB_BIT;
432 int rc = CrPtInit(&pDisplay->Presenter, crDpCbRegionsChanged, CrPtCbDrawEntrySingle, crDpCbDrawTextureWindow);
433 if (RT_SUCCESS(rc))
434 {
435 if (crServerMuralInit(&pDisplay->Mural, "", visBits, -1) >= 0)
436 {
437 return VINF_SUCCESS;
438// crServerMuralTerm(&pDisplay->Mural);
439 }
440 else
441 {
442 crWarning("crServerMuralInit failed!");
443 rc = VERR_GENERAL_FAILURE;
444 }
445 CrPtTerm(&pDisplay->Presenter);
446 }
447 CRASSERT(RT_FAILURE(rc));
448 return rc;
449}
450
451void CrDpTerm(PCR_DISPLAY pDisplay)
452{
453 CrPtTerm(&pDisplay->Presenter);
454 crServerMuralTerm(&pDisplay->Mural);
455}
456
457bool CrDpBlitterTest(PCR_DISPLAY pDisplay, PCR_BLITTER pBlitter)
458{
459 CrBltMuralSetCurrent(pBlitter, &pDisplay->Mural);
460 /* try to enter to make sure the blitter is initialized completely and to make sure we actually can do that */
461 int rc = CrBltEnter(pBlitter, cr_server.currentCtxInfo, cr_server.currentMural);
462 if (RT_SUCCESS(rc))
463 {
464 CrBltLeave(pBlitter);
465 return true;
466 }
467 else
468 {
469 crWarning("CrBltEnter failed, rc %d", rc);
470 }
471 return false;
472}
473
474void CrDpResize(PCR_DISPLAY pDisplay, uint32_t width, uint32_t height,
475 uint32_t stretchedWidth, uint32_t stretchedHeight)
476{
477 float StretchX, StretchY;
478 StretchX = ((float)stretchedWidth)/width;
479 StretchY = ((float)stretchedHeight)/height;
480 crServerMuralSize(&pDisplay->Mural, stretchedWidth, stretchedHeight);
481 CrPtSetStretching(&pDisplay->Presenter, StretchX, StretchY);
482}
483
484int CrDpPresentTexture(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
485{
486 return CrPtEntryPresent(&pDisplay->Presenter, &pEntry->Pe, pPos, cRegions, paRegions, pDisplay->pBlitter);
487}
488
489void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, PCR_BLITTER_TEXTURE pTextureData)
490{
491 CrPtEntryInit(&pEntry->Pe, pTextureData);
492}
493
494void CrDpEntryCleanup(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry)
495{
496 CrPtEntryRemove(&pDisplay->Presenter, &pEntry->Pe);
497}
498
499int CrDemInit(PCR_DISPLAY_ENTRY_MAP pMap)
500{
501 pMap->pTextureMap = crAllocHashtable();
502 if (pMap->pTextureMap)
503 return VINF_SUCCESS;
504
505 crWarning("crAllocHashtable failed!");
506 return VERR_NO_MEMORY;
507}
508
509void CrDemTerm(PCR_DISPLAY_ENTRY_MAP pMap)
510{
511 crFreeHashtable(pMap->pTextureMap, crFree);
512}
513
514PCR_DISPLAY_ENTRY CrDemEntryGetCreate(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture, CRContextInfo *pCtxInfo)
515{
516 PCR_DISPLAY_ENTRY pEntry = (PCR_DISPLAY_ENTRY)crHashtableSearch(pMap->pTextureMap, idTexture);
517 if (pEntry)
518 return pEntry;
519
520 CRContext *pContext = pCtxInfo->pContext;
521 if (!pContext)
522 {
523 crWarning("pContext is null!");
524 return NULL;
525 }
526
527 CRTextureObj *pTobj = (CRTextureObj*)crHashtableSearch(pContext->shared->textureTable, idTexture);
528 if (!pTobj)
529 {
530 crWarning("pTobj is null!");
531 return NULL;
532 }
533
534 GLuint hwId = crStateGetTextureObjHWID(pTobj);
535 if (!hwId)
536 {
537 crWarning("hwId is null!");
538 return NULL;
539 }
540
541 CR_BLITTER_TEXTURE TextureData;
542 TextureData.width = pTobj->level[0]->width;
543 TextureData.height = pTobj->level[0]->height;
544 TextureData.target = pTobj->target;
545 TextureData.hwid = hwId;
546
547 pEntry = (PCR_DISPLAY_ENTRY)crAlloc(sizeof (*pEntry));
548 if (!pEntry)
549 {
550 crWarning("crAlloc failed allocating CR_DISPLAY_ENTRY");
551 return NULL;
552 }
553
554 CrDpEntryInit(pEntry, &TextureData);
555
556 crHashtableAdd(pMap->pTextureMap, idTexture, pEntry);
557 return pEntry;
558
559}
560
561void CrDemEntryDestroy(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture)
562{
563#ifdef DEBUG
564 {
565 PCR_DISPLAY_ENTRY pEntry = (PCR_DISPLAY_ENTRY)crHashtableSearch(pMap->pTextureMap, idTexture);
566 if (!pEntry)
567 {
568 crWarning("request to delete inexistent entry");
569 return;
570 }
571
572 Assert(!CrDpEntryIsUsed(pEntry));
573 }
574#endif
575 crHashtableDelete(pMap->pTextureMap, idTexture, crFree);
576}
577
578#define CR_PRESENT_SCREEN_MASK 0xffff
579#define CR_PRESENT_FLAGS_OFFSET 16
580
581#define CR_PRESENT_GET_SCREEN(_cfg) ((_cfg) & CR_PRESENT_SCREEN_MASK)
582#define CR_PRESENT_GET_FLAGS(_cfg) ((_cfg) >> CR_PRESENT_FLAGS_OFFSET)
583
584static uint8_t crServerCheckInitDisplayBlitter()
585{
586 if (cr_server.fPresentBlitterInited)
587 return cr_server.fPresentBlitterInited;
588
589 crDebug("Display Functionality is requested");
590 Assert(!ASMBitTest(cr_server.DisplaysInitMap, 0));
591
592 int rc = CrDemInit(&cr_server.PresentTexturepMap);
593 if (RT_SUCCESS(rc))
594 {
595 rc = CrDpInit(&cr_server.aDispplays[0]);
596 if (RT_SUCCESS(rc))
597 {
598 CRMuralInfo*pMural = CrDpGetMural(&cr_server.aDispplays[0]);
599 CRCreateInfo_t*pCreateInfo = CrDpGetMuralCreateInfo(&cr_server.aDispplays[0]);
600 rc = CrBltInit(&cr_server.PresentBlitter, pMural, pCreateInfo->visualBits);
601 if (RT_SUCCESS(rc))
602 {
603 if (CrDpBlitterTest(&cr_server.aDispplays[0], &cr_server.PresentBlitter))
604 {
605 CrDpBlitterSet(&cr_server.aDispplays[0], &cr_server.PresentBlitter);
606 ASMBitSet(cr_server.DisplaysInitMap, 0);
607 cr_server.fPresentBlitterInited = 1;
608 return 1;
609 }
610 else
611 {
612 crWarning("CrDpBlitterTest failed");
613 }
614 CrBltTerm(&cr_server.PresentBlitter);
615 }
616 else
617 {
618 crWarning("CrBltInit failed, rc %d", rc);
619 }
620 CrDpTerm(&cr_server.aDispplays[0]);
621 }
622 else
623 {
624 crWarning("CrDpInit failed, rc %d", rc);
625 }
626 CrDemTerm(&cr_server.PresentTexturepMap);
627 }
628 else
629 {
630 crWarning("CrDemInit failed, rc %d", rc);
631 }
632
633 cr_server.fPresentBlitterInited = -1;
634 return -1;
635}
636
637static bool crServerDisplayIsSupported()
638{
639 return crServerCheckInitDisplayBlitter() > 0;
640}
641
642static PCR_DISPLAY crServerDisplayGet(uint32_t idScreen)
643{
644 if (idScreen >= CR_MAX_GUEST_MONITORS)
645 {
646 crWarning("invalid idScreen %d", idScreen);
647 return NULL;
648 }
649
650 if (ASMBitTest(cr_server.DisplaysInitMap, idScreen))
651 return &cr_server.aDispplays[idScreen];
652
653 if (crServerCheckInitDisplayBlitter() > 0)
654 {
655 /* the display (screen id == 0) can be initialized while doing crServerCheckInitDisplayBlitter,
656 * so re-check the bit map */
657 if (ASMBitTest(cr_server.DisplaysInitMap, idScreen))
658 return &cr_server.aDispplays[idScreen];
659
660 int rc = CrDpInit(&cr_server.aDispplays[idScreen]);
661 if (RT_SUCCESS(rc))
662 {
663 CrDpBlitterSet(&cr_server.aDispplays[idScreen], &cr_server.PresentBlitter);
664 ASMBitSet(cr_server.DisplaysInitMap, idScreen);
665 return &cr_server.aDispplays[idScreen];
666 }
667 else
668 {
669 crWarning("CrDpInit failed for screen %d", idScreen);
670 }
671 }
672 else
673 {
674 crWarning("crServerCheckInitDisplayBlitter said \"UNSUPPORTED\"");
675 }
676
677 return NULL;
678}
679
680void SERVER_DISPATCH_APIENTRY
681crServerDispatchTexPresent(GLuint texture, GLuint cfg, GLint xPos, GLint yPos, GLint cRects, GLint *pRects)
682{
683 uint32_t idScreen = CR_PRESENT_GET_SCREEN(cfg);
684 PCR_DISPLAY pDisplay = crServerDisplayGet(idScreen);
685 if (!pDisplay)
686 {
687 crWarning("crServerDisplayGet Failed");
688 return;
689 }
690
691 PCR_DISPLAY_ENTRY pEntry = CrDemEntryGetCreate(&cr_server.PresentTexturepMap, texture, cr_server.currentCtxInfo);
692 if (!pEntry)
693 {
694 crWarning("CrDemEntryGetCreate Failed");
695 return;
696 }
697
698 RTPOINT Point = {xPos, yPos};
699 int rc = CrDpPresentTexture(pDisplay, pEntry, &Point, (uint32_t)cRects, (const RTRECT*)pRects);
700 if (!RT_SUCCESS(rc))
701 {
702 crWarning("CrDpPresentTexture Failed rc %d", rc);
703 }
704}
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