VirtualBox

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

Last change on this file since 53167 was 53167, checked in by vboxsync, 11 years ago

Host 3D: Presentation framework: do not re-create 3D window on framebuffer sync (restored behavior prior to r96693); create 3D window on CrFbWindow class instance creation.

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