VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp@ 37845

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

Additions/Video: display/miniport drivers

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.9 KB
Line 
1/* $Id: VBoxDispMp.cpp 36867 2011-04-28 07:27:03Z vboxsync $ */
2
3/** @file
4 * VBoxVideo Display D3D User mode dll
5 */
6
7/*
8 * Copyright (C) 2011 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 "VBoxDispD3DCmn.h"
20#include "VBoxDispMp.h"
21
22#include <iprt/assert.h>
23
24typedef struct VBOXVIDEOCM_ITERATOR
25{
26 PVBOXVIDEOCM_CMD_HDR pCur;
27 uint32_t cbRemain;
28} VBOXVIDEOCM_ITERATOR, *PVBOXVIDEOCM_ITERATOR;
29
30typedef struct VBOXDISPMP
31{
32 PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pEscapeCmd;
33 uint32_t cbEscapeCmd;
34 VBOXVIDEOCM_ITERATOR Iterator;
35} VBOXDISPMP, *PVBOXDISPMP;
36
37DECLINLINE(void) vboxVideoCmIterInit(PVBOXVIDEOCM_ITERATOR pIter, PVBOXVIDEOCM_CMD_HDR pStart, uint32_t cbCmds)
38{
39 pIter->pCur = pStart;
40 pIter->cbRemain= cbCmds;
41}
42
43DECLINLINE(PVBOXVIDEOCM_CMD_HDR) vboxVideoCmIterNext(PVBOXVIDEOCM_ITERATOR pIter)
44{
45 if (pIter->cbRemain)
46 {
47 PVBOXVIDEOCM_CMD_HDR pCur = pIter->pCur;
48 Assert(pIter->cbRemain >= pIter->pCur->cbCmd);
49 pIter->cbRemain -= pIter->pCur->cbCmd;
50 pIter->pCur = (PVBOXVIDEOCM_CMD_HDR)(((uint8_t*)pIter->pCur) + pIter->pCur->cbCmd);
51 return pCur;
52 }
53 return NULL;
54}
55
56DECLINLINE(bool) vboxVideoCmIterHasNext(PVBOXVIDEOCM_ITERATOR pIter)
57{
58 return !!(pIter->cbRemain);
59}
60
61static VBOXDISPMP g_VBoxDispMp;
62
63DECLCALLBACK(HRESULT) vboxDispMpEnableEvents()
64{
65 g_VBoxDispMp.pEscapeCmd = NULL;
66 g_VBoxDispMp.cbEscapeCmd = 0;
67 vboxVideoCmIterInit(&g_VBoxDispMp.Iterator, NULL, 0);
68#ifdef VBOX_WITH_CRHGSMI
69 vboxUhgsmiGlobalSetCurrent();
70#endif
71 return S_OK;
72}
73
74
75DECLCALLBACK(HRESULT) vboxDispMpDisableEvents()
76{
77 if (g_VBoxDispMp.pEscapeCmd)
78 RTMemFree(g_VBoxDispMp.pEscapeCmd);
79#ifdef VBOX_WITH_CRHGSMI
80 vboxUhgsmiGlobalClearCurrent();
81#endif
82 return S_OK;
83}
84
85#define VBOXDISPMP_BUF_INITSIZE 4000
86#define VBOXDISPMP_BUF_INCREASE 4096
87#define VBOXDISPMP_BUF_MAXSIZE ((4096*4096)-96)
88
89DECLCALLBACK(HRESULT) vboxDispMpGetRegions(PVBOXDISPMP_REGIONS pRegions, DWORD dwMilliseconds)
90{
91 HRESULT hr = S_OK;
92 PVBOXVIDEOCM_CMD_HDR pHdr = vboxVideoCmIterNext(&g_VBoxDispMp.Iterator);
93 if (!pHdr)
94 {
95 if (!g_VBoxDispMp.pEscapeCmd)
96 {
97 g_VBoxDispMp.pEscapeCmd = (PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD)RTMemAlloc(VBOXDISPMP_BUF_INITSIZE);
98 Assert(g_VBoxDispMp.pEscapeCmd);
99 if (g_VBoxDispMp.pEscapeCmd)
100 g_VBoxDispMp.cbEscapeCmd = VBOXDISPMP_BUF_INITSIZE;
101 else
102 return E_OUTOFMEMORY;
103 }
104
105 do
106 {
107 hr = vboxDispCmCmdGet(g_VBoxDispMp.pEscapeCmd, g_VBoxDispMp.cbEscapeCmd, dwMilliseconds);
108 Assert(hr == S_OK || (dwMilliseconds != INFINITE && hr == WAIT_TIMEOUT));
109 if (hr == S_OK)
110 {
111 if (g_VBoxDispMp.pEscapeCmd->Hdr.cbCmdsReturned)
112 {
113 pHdr = (PVBOXVIDEOCM_CMD_HDR)(((uint8_t*)g_VBoxDispMp.pEscapeCmd) + sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD));
114 vboxVideoCmIterInit(&g_VBoxDispMp.Iterator, pHdr, g_VBoxDispMp.pEscapeCmd->Hdr.cbCmdsReturned);
115 pHdr = vboxVideoCmIterNext(&g_VBoxDispMp.Iterator);
116 Assert(pHdr);
117 break;
118 }
119 else
120 {
121 Assert(g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingCmds);
122 Assert(g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingFirstCmd);
123 RTMemFree(g_VBoxDispMp.pEscapeCmd);
124 uint32_t newSize = RT_MAX(g_VBoxDispMp.cbEscapeCmd + VBOXDISPMP_BUF_INCREASE, g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingFirstCmd);
125 if (newSize < VBOXDISPMP_BUF_MAXSIZE)
126 newSize = RT_MAX(newSize, RT_MIN(g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingCmds, VBOXDISPMP_BUF_MAXSIZE));
127 Assert(g_VBoxDispMp.cbEscapeCmd < newSize);
128 g_VBoxDispMp.pEscapeCmd = (PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD)RTMemAlloc(newSize);
129 Assert(g_VBoxDispMp.pEscapeCmd);
130 if (g_VBoxDispMp.pEscapeCmd)
131 g_VBoxDispMp.cbEscapeCmd = newSize;
132 else
133 {
134 g_VBoxDispMp.pEscapeCmd = NULL;
135 g_VBoxDispMp.cbEscapeCmd = 0;
136 hr = E_OUTOFMEMORY;
137 break;
138 }
139 }
140 }
141 else
142 break;
143 } while (1);
144 }
145
146 if (hr == S_OK)
147 {
148 Assert(pHdr);
149 VBOXWDDMDISP_CONTEXT *pContext = (VBOXWDDMDISP_CONTEXT*)pHdr->u64UmData;
150 PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)(((uint8_t*)pHdr) + sizeof (VBOXVIDEOCM_CMD_HDR));
151 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = (PVBOXWDDMDISP_SWAPCHAIN)pCmdInternal->hSwapchainUm;
152 /* todo: synchronization */
153 Assert(pSwapchain);
154 pRegions->hWnd = pSwapchain->hWnd;
155 pRegions->pRegions = &pCmdInternal->Cmd;
156 }
157 return hr;
158}
159
160static DECLCALLBACK(void) vboxDispMpLog(LPCSTR pszMsg)
161{
162 vboxDispCmLog(pszMsg);
163}
164
165VBOXDISPMP_DECL(HRESULT) VBoxDispMpGetCallbacks(uint32_t u32Version, PVBOXDISPMP_CALLBACKS pCallbacks)
166{
167 Assert(u32Version == VBOXDISPMP_VERSION);
168 if (u32Version != VBOXDISPMP_VERSION)
169 return E_INVALIDARG;
170
171 pCallbacks->pfnEnableEvents = vboxDispMpEnableEvents;
172 pCallbacks->pfnDisableEvents = vboxDispMpDisableEvents;
173 pCallbacks->pfnGetRegions = vboxDispMpGetRegions;
174 pCallbacks->pfnLog = vboxDispMpLog;
175 return S_OK;
176}
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