VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispMp.cpp@ 30483

Last change on this file since 30483 was 30483, checked in by vboxsync, 14 years ago

wddm/3d: visible regions impl & fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.3 KB
Line 
1/** @file
2 *
3 * VBoxVideo Display D3D User mode dll
4 *
5 * Copyright (C) 2010 Oracle Corporation
6 *
7 * This file is part of VirtualBox Open Source Edition (OSE), as
8 * available from http://www.virtualbox.org. This file is free software;
9 * you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License (GPL) as published by the Free Software
11 * Foundation, in version 2 as it comes in the "COPYING" file of the
12 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
14 */
15#include "VBoxDispD3DCmn.h"
16#include "VBoxDispMp.h"
17
18#include <iprt/assert.h>
19
20typedef struct VBOXVIDEOCM_ITERATOR
21{
22 PVBOXVIDEOCM_CMD_HDR pCur;
23 uint32_t cbRemain;
24} VBOXVIDEOCM_ITERATOR, *PVBOXVIDEOCM_ITERATOR;
25
26typedef struct VBOXDISPMP
27{
28 PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pEscapeCmd;
29 uint32_t cbEscapeCmd;
30 VBOXVIDEOCM_ITERATOR Iterator;
31} VBOXDISPMP, *PVBOXDISPMP;
32
33DECLINLINE(void) vboxVideoCmIterInit(PVBOXVIDEOCM_ITERATOR pIter, PVBOXVIDEOCM_CMD_HDR pStart, uint32_t cbCmds)
34{
35 pIter->pCur = pStart;
36 pIter->cbRemain= cbCmds;
37}
38
39DECLINLINE(PVBOXVIDEOCM_CMD_HDR) vboxVideoCmIterNext(PVBOXVIDEOCM_ITERATOR pIter)
40{
41 if (pIter->cbRemain)
42 {
43 Assert(pIter->cbRemain >= pIter->pCur->cbCmd);
44 pIter->cbRemain -= pIter->pCur->cbCmd;
45 pIter->pCur = (PVBOXVIDEOCM_CMD_HDR)(((uint8_t*)pIter->pCur) + pIter->pCur->cbCmd);
46 return pIter->pCur;
47 }
48 return NULL;
49}
50
51DECLINLINE(bool) vboxVideoCmIterHasNext(PVBOXVIDEOCM_ITERATOR pIter)
52{
53 return !!(pIter->cbRemain);
54}
55
56static VBOXDISPMP g_VBoxDispMp;
57
58DECLCALLBACK(HRESULT) vboxDispMpEnableEvents()
59{
60 g_VBoxDispMp.pEscapeCmd = NULL;
61 g_VBoxDispMp.cbEscapeCmd = 0;
62 vboxVideoCmIterInit(&g_VBoxDispMp.Iterator, NULL, 0);
63 return S_OK;
64}
65
66
67DECLCALLBACK(HRESULT) vboxDispMpDisableEvents()
68{
69 if (g_VBoxDispMp.pEscapeCmd)
70 RTMemFree(g_VBoxDispMp.pEscapeCmd);
71 return S_OK;
72}
73
74#define VBOXDISPMP_BUF_INITSIZE 4000
75#define VBOXDISPMP_BUF_INCREASE 4096
76#define VBOXDISPMP_BUF_MAXSIZE ((4096*4096)-96)
77
78DECLCALLBACK(HRESULT) vboxDispMpGetRegions(PVBOXDISPMP_REGIONS pRegions, DWORD dwMilliseconds)
79{
80 HRESULT hr = S_OK;
81 PVBOXVIDEOCM_CMD_HDR pHdr = vboxVideoCmIterNext(&g_VBoxDispMp.Iterator);
82 if (!pHdr)
83 {
84 if (!g_VBoxDispMp.pEscapeCmd)
85 {
86 g_VBoxDispMp.pEscapeCmd = (PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD)RTMemAlloc(VBOXDISPMP_BUF_INITSIZE);
87 Assert(g_VBoxDispMp.pEscapeCmd);
88 if (g_VBoxDispMp.pEscapeCmd)
89 g_VBoxDispMp.cbEscapeCmd = VBOXDISPMP_BUF_INITSIZE;
90 else
91 return E_OUTOFMEMORY;
92 }
93
94 do
95 {
96 hr = vboxDispCmCmdGet(g_VBoxDispMp.pEscapeCmd, g_VBoxDispMp.cbEscapeCmd, dwMilliseconds);
97 Assert(hr == S_OK);
98 if (hr == S_OK)
99 {
100 if (g_VBoxDispMp.pEscapeCmd->Hdr.cbCmdsReturned)
101 {
102 PVBOXVIDEOCM_CMD_HDR pHdr = (PVBOXVIDEOCM_CMD_HDR)(((uint8_t*)g_VBoxDispMp.pEscapeCmd) + sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD));
103 vboxVideoCmIterInit(&g_VBoxDispMp.Iterator, pHdr, g_VBoxDispMp.pEscapeCmd->Hdr.cbCmdsReturned);
104 pHdr = vboxVideoCmIterNext(&g_VBoxDispMp.Iterator);
105 Assert(pHdr);
106 break;
107 }
108 else
109 {
110 Assert(g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingCmds);
111 Assert(g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingFirstCmd);
112 RTMemFree(g_VBoxDispMp.pEscapeCmd);
113 uint32_t newSize = RT_MAX(g_VBoxDispMp.cbEscapeCmd + VBOXDISPMP_BUF_INCREASE, g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingFirstCmd);
114 if (newSize < VBOXDISPMP_BUF_MAXSIZE)
115 newSize = RT_MAX(newSize, RT_MIN(g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingCmds, VBOXDISPMP_BUF_MAXSIZE));
116 Assert(g_VBoxDispMp.cbEscapeCmd < newSize);
117 g_VBoxDispMp.pEscapeCmd = (PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD)RTMemAlloc(newSize);
118 Assert(g_VBoxDispMp.pEscapeCmd);
119 if (g_VBoxDispMp.pEscapeCmd)
120 g_VBoxDispMp.cbEscapeCmd = newSize;
121 else
122 {
123 g_VBoxDispMp.pEscapeCmd = NULL;
124 g_VBoxDispMp.cbEscapeCmd = 0;
125 hr = E_OUTOFMEMORY;
126 break;
127 }
128 }
129 }
130 else
131 break;
132 } while (1);
133 }
134
135 if (hr == S_OK)
136 {
137 Assert(pHdr);
138 VBOXWDDMDISP_CONTEXT *pContext = (VBOXWDDMDISP_CONTEXT*)pHdr->u64UmData;
139 Assert(pContext->pDevice->hWnd);
140 pRegions->hWnd = pContext->pDevice->hWnd;
141 pRegions->pRegions = (PVBOXVIDEOCM_CMD_RECTS)(((uint8_t*)pHdr) + sizeof (VBOXVIDEOCM_CMD_HDR));
142 }
143 return hr;
144}
145
146VBOXDISPMP_DECL(HRESULT) VBoxDispMpGetCallbacks(uint32_t u32Version, PVBOXDISPMP_CALLBACKS pCallbacks)
147{
148 Assert(u32Version == VBOXDISPMP_VERSION);
149 if (u32Version != VBOXDISPMP_VERSION)
150 return E_INVALIDARG;
151
152 pCallbacks->pfnEnableEvents = vboxDispMpEnableEvents;
153 pCallbacks->pfnDisableEvents = vboxDispMpDisableEvents;
154 pCallbacks->pfnGetRegions = vboxDispMpGetRegions;
155 return S_OK;
156}
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