VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/presenter/window.cpp@ 53262

Last change on this file since 53262 was 53262, checked in by vboxsync, 10 years ago

Revert r96781, r96707 and r96693 since these commits affect 3D overlay window badly on Windows host.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.8 KB
Line 
1/* $Id: window.cpp 53262 2014-11-07 13:06:25Z vboxsync $ */
2
3/** @file
4 * Presenter API: window class implementation.
5 */
6
7/*
8 * Copyright (C) 2014 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 "server_presenter.h"
20
21
22CrFbWindow::CrFbWindow(uint64_t parentId) :
23 mSpuWindow(0),
24 mpCompositor(NULL),
25 mcUpdates(0),
26 mxPos(0),
27 myPos(0),
28 mWidth(0),
29 mHeight(0),
30 mParentId(parentId)
31{
32 mFlags.Value = 0;
33}
34
35
36bool CrFbWindow::IsCreated() const
37{
38 return !!mSpuWindow;
39}
40
41bool CrFbWindow::IsVisivle() const
42{
43 return mFlags.fVisible;
44}
45
46
47void CrFbWindow::Destroy()
48{
49 CRASSERT(!mcUpdates);
50
51 if (!mSpuWindow)
52 return;
53
54 cr_server.head_spu->dispatch_table.WindowDestroy(mSpuWindow);
55
56 mSpuWindow = 0;
57 mFlags.fDataPresented = 0;
58}
59
60
61int CrFbWindow::Reparent(uint64_t parentId)
62{
63 if (!checkInitedUpdating())
64 {
65 WARN(("err"));
66 return VERR_INVALID_STATE;
67 }
68
69 crDebug("CrFbWindow: reparent to %p (current mxPos=%d, myPos=%d, mWidth=%u, mHeight=%u)",
70 parentId, mxPos, myPos, mWidth, mHeight);
71
72 uint64_t oldParentId = mParentId;
73
74 mParentId = parentId;
75
76 if (mSpuWindow)
77 {
78 if (oldParentId && !parentId && mFlags.fVisible)
79 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, false);
80
81 renderspuSetWindowId(mParentId);
82 renderspuReparentWindow(mSpuWindow);
83 renderspuSetWindowId(cr_server.screen[0].winID);
84
85 if (parentId)
86 {
87 if (mFlags.fVisible)
88 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, mxPos, myPos);
89 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, mFlags.fVisible);
90 }
91 }
92
93 return VINF_SUCCESS;
94}
95
96
97int CrFbWindow::SetVisible(bool fVisible)
98{
99 if (!checkInitedUpdating())
100 {
101 WARN(("err"));
102 return VERR_INVALID_STATE;
103 }
104
105 LOG(("CrWIN: Visible [%d]", fVisible));
106
107 if (!fVisible != !mFlags.fVisible)
108 {
109 mFlags.fVisible = fVisible;
110 if (mSpuWindow && mParentId)
111 {
112 if (fVisible)
113 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, mxPos, myPos);
114 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, fVisible);
115 }
116 }
117
118 return VINF_SUCCESS;
119}
120
121
122int CrFbWindow::SetSize(uint32_t width, uint32_t height)
123{
124 if (!checkInitedUpdating())
125 {
126 WARN(("err"));
127 return VERR_INVALID_STATE;
128 }
129
130 LOG(("CrWIN: Size [%d ; %d]", width, height));
131
132 if (mWidth != width || mHeight != height)
133 {
134 mFlags.fCompositoEntriesModified = 1;
135 mWidth = width;
136 mHeight = height;
137 if (mSpuWindow)
138 cr_server.head_spu->dispatch_table.WindowSize(mSpuWindow, width, height);
139 }
140
141 return VINF_SUCCESS;
142}
143
144
145int CrFbWindow::SetPosition(int32_t x, int32_t y)
146{
147 if (!checkInitedUpdating())
148 {
149 WARN(("err"));
150 return VERR_INVALID_STATE;
151 }
152
153 LOG(("CrWIN: Pos [%d ; %d]", x, y));
154// always do WindowPosition to ensure window is adjusted properly
155// if (x != mxPos || y != myPos)
156 {
157 mxPos = x;
158 myPos = y;
159 if (mSpuWindow)
160 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, x, y);
161 }
162
163 return VINF_SUCCESS;
164}
165
166
167int CrFbWindow::SetVisibleRegionsChanged()
168{
169 if (!checkInitedUpdating())
170 {
171 WARN(("err"));
172 return VERR_INVALID_STATE;
173 }
174
175 mFlags.fCompositoEntriesModified = 1;
176 return VINF_SUCCESS;
177}
178
179
180int CrFbWindow::SetCompositor(const struct VBOXVR_SCR_COMPOSITOR * pCompositor)
181{
182 if (!checkInitedUpdating())
183 {
184 WARN(("err"));
185 return VERR_INVALID_STATE;
186 }
187
188 mpCompositor = pCompositor;
189 mFlags.fCompositoEntriesModified = 1;
190
191 return VINF_SUCCESS;
192}
193
194
195int CrFbWindow::UpdateBegin()
196{
197 ++mcUpdates;
198 if (mcUpdates > 1)
199 return VINF_SUCCESS;
200
201 Assert(!mFlags.fForcePresentOnReenable);
202
203 if (mFlags.fDataPresented)
204 {
205 Assert(mSpuWindow);
206 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mSpuWindow, NULL, NULL);
207 mFlags.fForcePresentOnReenable = isPresentNeeded();
208 }
209
210 return VINF_SUCCESS;
211}
212
213
214void CrFbWindow::UpdateEnd()
215{
216 --mcUpdates;
217 Assert(mcUpdates < UINT32_MAX/2);
218 if (mcUpdates)
219 return;
220
221 checkRegions();
222
223 if (mSpuWindow)
224 {
225 bool fPresentNeeded = isPresentNeeded();
226 if (fPresentNeeded || mFlags.fForcePresentOnReenable)
227 {
228 mFlags.fForcePresentOnReenable = false;
229 if (mpCompositor)
230 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mSpuWindow, mpCompositor, NULL);
231 else
232 {
233 VBOXVR_SCR_COMPOSITOR TmpCompositor;
234 RTRECT Rect;
235 Rect.xLeft = 0;
236 Rect.yTop = 0;
237 Rect.xRight = mWidth;
238 Rect.yBottom = mHeight;
239 CrVrScrCompositorInit(&TmpCompositor, &Rect);
240 /* this is a cleanup operation
241 * empty compositor is guarantid to be released on VBoxPresentComposition return */
242 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mSpuWindow, &TmpCompositor, NULL);
243 }
244 g_pLed->Asserted.s.fWriting = 1;
245 }
246
247 /* even if the above branch is entered due to mFlags.fForcePresentOnReenable,
248 * the backend should clean up the compositor as soon as presentation is performed */
249 mFlags.fDataPresented = fPresentNeeded;
250 }
251 else
252 {
253 Assert(!mFlags.fDataPresented);
254 Assert(!mFlags.fForcePresentOnReenable);
255 }
256}
257
258
259uint64_t CrFbWindow::GetParentId()
260{
261 return mParentId;
262}
263
264
265int CrFbWindow::Create()
266{
267 if (mSpuWindow)
268 {
269 //WARN(("window already created"));
270 return VINF_ALREADY_INITIALIZED;
271 }
272
273 CRASSERT(cr_server.fVisualBitsDefault);
274 renderspuSetWindowId(mParentId);
275 mSpuWindow = cr_server.head_spu->dispatch_table.WindowCreate("", cr_server.fVisualBitsDefault);
276 renderspuSetWindowId(cr_server.screen[0].winID);
277 if (mSpuWindow < 0) {
278 WARN(("WindowCreate failed"));
279 return VERR_GENERAL_FAILURE;
280 }
281
282 cr_server.head_spu->dispatch_table.WindowSize(mSpuWindow, mWidth, mHeight);
283 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, mxPos, myPos);
284
285 checkRegions();
286
287 if (mParentId && mFlags.fVisible)
288 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, true);
289
290 return VINF_SUCCESS;
291}
292
293
294CrFbWindow::~CrFbWindow()
295{
296 Destroy();
297}
298
299
300void CrFbWindow::checkRegions()
301{
302 if (!mSpuWindow)
303 return;
304
305 if (!mFlags.fCompositoEntriesModified)
306 return;
307
308 uint32_t cRects;
309 const RTRECT *pRects;
310 if (mpCompositor)
311 {
312 int rc = CrVrScrCompositorRegionsGet(mpCompositor, &cRects, NULL, &pRects, NULL);
313 if (!RT_SUCCESS(rc))
314 {
315 WARN(("CrVrScrCompositorRegionsGet failed rc %d", rc));
316 cRects = 0;
317 pRects = NULL;
318 }
319 }
320 else
321 {
322 cRects = 0;
323 pRects = NULL;
324 }
325
326 cr_server.head_spu->dispatch_table.WindowVisibleRegion(mSpuWindow, cRects, (const GLint*)pRects);
327
328 mFlags.fCompositoEntriesModified = 0;
329}
330
331
332bool CrFbWindow::isPresentNeeded()
333{
334 return mFlags.fVisible && mWidth && mHeight && mpCompositor && !CrVrScrCompositorIsEmpty(mpCompositor);
335}
336
337
338bool CrFbWindow::checkInitedUpdating()
339{
340 if (!mcUpdates)
341 {
342 WARN(("not updating"));
343 return false;
344 }
345
346 return true;
347}
348
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