VirtualBox

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

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

wddm/crOpenGL: more TexPresent fixes

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