VirtualBox

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

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

crOpenGL: OSX backend rework; oddscreen rendering generalization

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.0 KB
Line 
1/* $Id: server_presenter.cpp 44740 2013-02-18 17:02:47Z vboxsync $ */
2
3/** @file
4 * Presenter API
5 */
6
7/*
8 * Copyright (C) 2012-2013 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
34
35/* DISPLAY */
36
37//static DECLCALLBACK(int) crDpCbRegionsChanged(struct CR_PRESENTER *pPresenter)
38//{
39// uint32_t cRegions;
40// const RTRECT *paRegions;
41// int rc = CrPtGetRegions(pPresenter, &cRegions, &paRegions);
42// if (!RT_SUCCESS(rc))
43// {
44// crWarning("CrPtGetRegions failed, rc %d", rc);
45// return rc;
46// }
47//
48// PCR_DISPLAY pDisplay = CR_DISPLAY_FROM_PRESENTER(pPresenter);
49//
50// cr_server.head_spu->dispatch_table.WindowVisibleRegion(pDisplay->Mural.spuWindow, cRegions, (GLint*)paRegions);
51//
52// if (pDisplay->Mural.pvOutputRedirectInstance)
53// {
54// /* @todo the code assumes that RTRECT == four GLInts. */
55// cr_server.outputRedirect.CRORVisibleRegion(pDisplay->Mural.pvOutputRedirectInstance,
56// cRegions, paRegions);
57// }
58//
59// return VINF_SUCCESS;
60//}
61
62int CrDpInit(PCR_DISPLAY pDisplay)
63{
64 int rc = CrVrScrCompositorInit(&pDisplay->Compositor);
65 if (RT_SUCCESS(rc))
66 {
67 const GLint visBits = CR_RGB_BIT | CR_DOUBLE_BIT;
68 if (crServerMuralInit(&pDisplay->Mural, "", visBits, -1) >= 0)
69 {
70 return VINF_SUCCESS;
71// crServerMuralTerm(&pDisplay->Mural);
72 }
73 else
74 {
75 crWarning("crServerMuralInit failed!");
76 rc = VERR_GENERAL_FAILURE;
77 }
78 CrVrScrCompositorTerm(&pDisplay->Compositor);
79 }
80 else
81 {
82 crWarning("CrVrScrCompositorInit failed, rc %d", rc);
83 }
84 CRASSERT(RT_FAILURE(rc));
85 return rc;
86}
87
88void CrDpTerm(PCR_DISPLAY pDisplay)
89{
90 CrVrScrCompositorTerm(&pDisplay->Compositor);
91 crServerMuralTerm(&pDisplay->Mural);
92}
93
94void CrDpResize(PCR_DISPLAY pDisplay, uint32_t width, uint32_t height,
95 uint32_t stretchedWidth, uint32_t stretchedHeight)
96{
97 float StretchX, StretchY;
98 StretchX = ((float)stretchedWidth)/width;
99 StretchY = ((float)stretchedHeight)/height;
100 crServerMuralSize(&pDisplay->Mural, stretchedWidth, stretchedHeight);
101 CrVrScrCompositorSetStretching(&pDisplay->Compositor, StretchX, StretchY);
102}
103
104int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
105{
106 return CrVrScrCompositorEntryRegionsSet(&pDisplay->Compositor, &pEntry->CEntry, pPos, cRegions, paRegions);
107}
108
109int CrDpEntryRegionsAdd(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
110{
111 return CrVrScrCompositorEntryRegionsAdd(&pDisplay->Compositor, &pEntry->CEntry, pPos, cRegions, paRegions);
112}
113
114int CrDpPresentEntry(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry)
115{
116 GLuint idDrawFBO = 0, idReadFBO = 0;
117 CRMuralInfo *pMural = cr_server.currentMural;
118 CRContext *pCtx = cr_server.currentCtxInfo ? cr_server.currentCtxInfo->pContext : cr_server.MainContextInfo.pContext;
119
120 if (pMural)
121 {
122 idDrawFBO = pMural->aidFBOs[pMural->iCurDrawBuffer];
123 idReadFBO = pMural->aidFBOs[pMural->iCurReadBuffer];
124 }
125
126 crStateSwitchPrepare(NULL, pCtx, idDrawFBO, idReadFBO);
127
128 cr_server.head_spu->dispatch_table.VBoxPresentComposition(pDisplay->Mural.spuWindow, &pDisplay->Compositor, &pEntry->CEntry);
129
130 crStateSwitchPostprocess(pCtx, NULL, idDrawFBO, idReadFBO);
131
132 return VINF_SUCCESS;
133}
134
135void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const PVBOXVR_TEXTURE pTextureData)
136{
137 CrVrScrCompositorEntryInit(&pEntry->CEntry, pTextureData);
138}
139
140void CrDpEntryCleanup(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry)
141{
142 CrVrScrCompositorEntryRemove(&pDisplay->Compositor, &pEntry->CEntry);
143}
144
145int CrDemInit(PCR_DISPLAY_ENTRY_MAP pMap)
146{
147 pMap->pTextureMap = crAllocHashtable();
148 if (pMap->pTextureMap)
149 return VINF_SUCCESS;
150
151 crWarning("crAllocHashtable failed!");
152 return VERR_NO_MEMORY;
153}
154
155void CrDemTerm(PCR_DISPLAY_ENTRY_MAP pMap)
156{
157 crFreeHashtable(pMap->pTextureMap, crFree);
158}
159
160PCR_DISPLAY_ENTRY CrDemEntryGetCreate(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture, CRContextInfo *pCtxInfo)
161{
162 PCR_DISPLAY_ENTRY pEntry = (PCR_DISPLAY_ENTRY)crHashtableSearch(pMap->pTextureMap, idTexture);
163 if (pEntry)
164 return pEntry;
165
166 CRContext *pContext = pCtxInfo->pContext;
167 if (!pContext)
168 {
169 crWarning("pContext is null!");
170 return NULL;
171 }
172
173 CRTextureObj *pTobj = (CRTextureObj*)crHashtableSearch(pContext->shared->textureTable, idTexture);
174 if (!pTobj)
175 {
176 crWarning("pTobj is null!");
177 return NULL;
178 }
179
180 GLuint hwId = crStateGetTextureObjHWID(pTobj);
181 if (!hwId)
182 {
183 crWarning("hwId is null!");
184 return NULL;
185 }
186
187 VBOXVR_TEXTURE TextureData;
188 TextureData.width = pTobj->level[0]->width;
189 TextureData.height = pTobj->level[0]->height;
190 TextureData.target = pTobj->target;
191 TextureData.hwid = hwId;
192
193 pEntry = (PCR_DISPLAY_ENTRY)crAlloc(sizeof (*pEntry));
194 if (!pEntry)
195 {
196 crWarning("crAlloc failed allocating CR_DISPLAY_ENTRY");
197 return NULL;
198 }
199
200 CrDpEntryInit(pEntry, &TextureData);
201
202 crHashtableAdd(pMap->pTextureMap, idTexture, pEntry);
203 return pEntry;
204
205}
206
207void CrDemEntryDestroy(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture)
208{
209#ifdef DEBUG
210 {
211 PCR_DISPLAY_ENTRY pEntry = (PCR_DISPLAY_ENTRY)crHashtableSearch(pMap->pTextureMap, idTexture);
212 if (!pEntry)
213 {
214 crWarning("request to delete inexistent entry");
215 return;
216 }
217
218 Assert(!CrDpEntryIsUsed(pEntry));
219 }
220#endif
221 crHashtableDelete(pMap->pTextureMap, idTexture, crFree);
222}
223
224#define CR_PRESENT_SCREEN_MASK 0xffff
225#define CR_PRESENT_FLAGS_OFFSET 16
226
227#define CR_PRESENT_GET_SCREEN(_cfg) ((_cfg) & CR_PRESENT_SCREEN_MASK)
228#define CR_PRESENT_GET_FLAGS(_cfg) ((_cfg) >> CR_PRESENT_FLAGS_OFFSET)
229
230PCR_DISPLAY crServerDisplayGetInitialized(uint32_t idScreen)
231{
232 if (ASMBitTest(cr_server.DisplaysInitMap, idScreen))
233 return &cr_server.aDispplays[idScreen];
234 return NULL;
235}
236
237static PCR_DISPLAY crServerDisplayGet(uint32_t idScreen)
238{
239 if (idScreen >= CR_MAX_GUEST_MONITORS)
240 {
241 crWarning("invalid idScreen %d", idScreen);
242 return NULL;
243 }
244
245 if (ASMBitTest(cr_server.DisplaysInitMap, idScreen))
246 return &cr_server.aDispplays[idScreen];
247
248 /* the display (screen id == 0) can be initialized while doing crServerCheckInitDisplayBlitter,
249 * so re-check the bit map */
250 if (ASMBitTest(cr_server.DisplaysInitMap, idScreen))
251 return &cr_server.aDispplays[idScreen];
252
253 int rc = CrDpInit(&cr_server.aDispplays[idScreen]);
254 if (RT_SUCCESS(rc))
255 {
256 CrDpResize(&cr_server.aDispplays[idScreen],
257 cr_server.screen[idScreen].w, cr_server.screen[idScreen].h,
258 cr_server.screen[idScreen].w, cr_server.screen[idScreen].h);
259 ASMBitSet(cr_server.DisplaysInitMap, idScreen);
260 return &cr_server.aDispplays[idScreen];
261 }
262 else
263 {
264 crWarning("CrDpInit failed for screen %d", idScreen);
265 }
266
267 return NULL;
268}
269
270void CrHlpFreeTexImage(CRContext *pCurCtx, GLuint idPBO, void *pvData)
271{
272 if (idPBO)
273 {
274 cr_server.head_spu->dispatch_table.UnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
275 if (pCurCtx)
276 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pCurCtx->bufferobject.packBuffer->hwid);
277 else
278 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
279 }
280 else
281 {
282 crFree(pvData);
283 if (pCurCtx && crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_PACK_BUFFER_ARB))
284 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pCurCtx->bufferobject.packBuffer->hwid);
285 }
286}
287
288void* CrHlpGetTexImage(CRContext *pCurCtx, PVBOXVR_TEXTURE pTexture, GLuint idPBO)
289{
290 void *pvData = NULL;
291 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, pTexture->hwid);
292
293 if (idPBO)
294 {
295 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, idPBO);
296 }
297 else
298 {
299 if (!pCurCtx || crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_PACK_BUFFER_ARB))
300 {
301 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
302 }
303
304 pvData = crAlloc(4*pTexture->width*pTexture->height);
305 if (!pvData)
306 {
307 crWarning("Out of memory in CrHlpGetTexImage");
308 return NULL;
309 }
310 }
311
312 /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/
313 cr_server.head_spu->dispatch_table.GetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, pvData);
314
315 /*restore gl state*/
316 if (pCurCtx)
317 {
318 CRTextureObj *pTObj;
319 CRTextureLevel *pTImg;
320 crStateGetTextureObjectAndImage(pCurCtx, pTexture->target, 0, &pTObj, &pTImg);
321
322 GLuint uid = pTObj->hwid;
323 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, uid);
324 }
325 else
326 {
327 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, 0);
328 }
329
330 if (idPBO)
331 {
332 pvData = cr_server.head_spu->dispatch_table.MapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
333 if (!pvData)
334 {
335 crWarning("Failed to MapBuffer in CrHlpGetTexImage");
336 return NULL;
337 }
338 }
339
340 CRASSERT(pvData);
341 return pvData;
342}
343
344void SERVER_DISPATCH_APIENTRY
345crServerDispatchVBoxTexPresent(GLuint texture, GLuint cfg, GLint xPos, GLint yPos, GLint cRects, GLint *pRects)
346{
347 uint32_t idScreen = CR_PRESENT_GET_SCREEN(cfg);
348 PCR_DISPLAY pDisplay = crServerDisplayGet(idScreen);
349 if (!pDisplay)
350 {
351 crWarning("crServerDisplayGet Failed");
352 return;
353 }
354
355 PCR_DISPLAY_ENTRY pEntry = CrDemEntryGetCreate(&cr_server.PresentTexturepMap, texture, cr_server.currentCtxInfo);
356 if (!pEntry)
357 {
358 crWarning("CrDemEntryGetCreate Failed");
359 return;
360 }
361
362 RTPOINT Point = {xPos, yPos};
363 int rc = CrDpEntryRegionsAdd(pDisplay, pEntry, &Point, (uint32_t)cRects, (const RTRECT*)pRects);
364 if (!RT_SUCCESS(rc))
365 {
366 crWarning("CrDpEntrySetRegions Failed rc %d", rc);
367 return;
368 }
369
370 rc = CrDpPresentEntry(pDisplay, pEntry);
371 if (!RT_SUCCESS(rc))
372 {
373 crWarning("CrDpEntrySetRegions Failed rc %d", rc);
374 return;
375 }
376}
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